Skip to content

Commit c45b5da

Browse files
committed
make Keyed a class
1 parent 4977835 commit c45b5da

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

src/client/parts.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
is_renderable,
77
single_part_template,
88
unwrap_html,
9+
unwrap_keyed,
910
type Displayable,
1011
type Key,
1112
type Renderable,
@@ -120,7 +121,7 @@ export function create_child_part(
120121
let i = 0
121122
let end = span._start
122123
for (const item of value) {
123-
const key = is_keyed(item) ? item._key : (item as Key)
124+
const key = is_keyed(item) ? unwrap_keyed(item) : (item as Key)
124125
if (entries.length <= i) {
125126
const span = create_span_after(end)
126127
entries[i] = { _span: span, _part: create_child_part(span), _key: key }

src/client/root.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
is_renderable,
77
single_part_template,
88
unwrap_html,
9+
unwrap_keyed,
910
type Displayable,
1011
type Key,
1112
type Renderable,
@@ -97,7 +98,7 @@ function hydrate_child_part(span: Span, value: unknown) {
9798
let end = span._start
9899

99100
for (const item of value) {
100-
const key = is_keyed(item) ? item._key : (item as Key)
101+
const key = is_keyed(item) ? unwrap_keyed(item) : (item as Key)
101102

102103
const start = end.nextSibling
103104
assert(start && is_comment(start) && start.data === '?[')

src/shared.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function assert(value: unknown, message?: string): asserts value {
3232
}
3333

3434
export let unwrap_html: (value: HTML) => { _statics: TemplateStringsArray; _dynamics: unknown[] }
35+
export let unwrap_keyed: (value: Keyed) => Key
3536

3637
export class HTML {
3738
#statics: TemplateStringsArray
@@ -58,20 +59,26 @@ export function single_part_template(part: Displayable): HTML {
5859
}
5960

6061
export type Key = string | number | bigint | boolean | symbol | object | null
61-
export interface Keyed extends Renderable {
62-
[keyed_tag]: true
63-
/** @internal */ _key: Key
62+
63+
export class Keyed implements Renderable {
64+
#key: Key
65+
#displayable: Displayable
66+
constructor(displayable: Displayable, key: Key) {
67+
this.#key = key
68+
this.#displayable = displayable
69+
}
70+
render(): Displayable {
71+
return this.#displayable
72+
}
73+
static {
74+
unwrap_keyed = value => value.#key
75+
}
6476
}
6577

66-
const keyed_tag: unique symbol = Symbol()
6778
export function keyed(displayable: Displayable, key: Key): Keyed {
68-
return {
69-
[keyed_tag]: true,
70-
_key: key,
71-
render: () => displayable,
72-
}
79+
return new Keyed(displayable, key)
7380
}
7481

75-
export function is_keyed(value: any): value is Keyed {
76-
return typeof value === 'object' && value !== null && keyed_tag in value
82+
export function is_keyed(value: unknown): value is Keyed {
83+
return value instanceof Keyed
7784
}

0 commit comments

Comments
 (0)