@sigil-dev/runtime 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -381,6 +381,15 @@ export function createProfilerEffect(
381
381
  });
382
382
  }
383
383
 
384
+ // Deferred effect mode for hydration: effects created while the flag is set
385
+ // are queued instead of run immediately, then flushed after DOM insertion.
386
+ const deferredEffectQueue: (() => void)[] = [];
387
+
388
+ export function flushDeferredEffects(): void {
389
+ const pending = deferredEffectQueue.splice(0);
390
+ for (const run of pending) run();
391
+ }
392
+
384
393
  // biome-ignore lint/suspicious/noConfusingVoidType: please shut up its a weird type
385
394
  export function createEffect(fn: () => void | (() => void)): () => void {
386
395
  let cleanup: (() => void) | undefined;
@@ -404,7 +413,13 @@ export function createEffect(fn: () => void | (() => void)): () => void {
404
413
  }
405
414
  };
406
415
 
407
- effect();
416
+ // In deferred mode (hydration), queue the effect instead of running immediately.
417
+ // This ensures the DOM is inserted before effect callbacks query it.
418
+ if ((globalThis as any).__sigilDeferEffects) {
419
+ deferredEffectQueue.push(() => effect());
420
+ } else {
421
+ effect();
422
+ }
408
423
 
409
424
  const dispose = () => {
410
425
  for (const depSet of ownDeps) depSet.delete(effect);
@@ -551,7 +566,11 @@ export function reconcile<T>(
551
566
  const item = newItems[i]!;
552
567
  const key = getKey(item, i);
553
568
  let node = keyMap.get(key);
554
- if (node && lastItemFor.has(node) && !Object.is(lastItemFor.get(node), item)) {
569
+ if (
570
+ node &&
571
+ lastItemFor.has(node) &&
572
+ !Object.is(lastItemFor.get(node), item)
573
+ ) {
555
574
  node.parentNode?.removeChild(node);
556
575
  keyMap.delete(key);
557
576
  node = undefined;
package/jsr.json CHANGED
@@ -1,8 +1,8 @@
1
- {
2
- "name": "@sigil-dev/runtime",
3
- "version": "0.6.0",
4
- "exports": "./index.ts",
5
- "publish": {
6
- "exclude": ["src/**/*.test.ts"]
7
- }
8
- }
1
+ {
2
+ "name": "@sigil-dev/runtime",
3
+ "version": "0.6.0",
4
+ "exports": "./index.ts",
5
+ "publish": {
6
+ "exclude": ["src/**/*.test.ts"]
7
+ }
8
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@sigil-dev/runtime",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.9.4",
5
+ "version": "0.9.5",
6
6
  "description": "Runtime for the Sigil framework",
7
7
  "private": false,
8
8
  "devDependencies": {
package/reactivity/map.ts CHANGED
@@ -1,98 +1,98 @@
1
- import { createSignal, type Signal } from "../index.ts";
2
-
3
- export class ReactiveMap<K, V> extends Map<K, V> {
4
- #keyVersions: Map<K, Signal<number>> = new Map();
5
- #structVersion: Signal<number>;
6
- #structVal: number = 0;
7
- #getKeyVersion(key: K): Signal<number> {
8
- let sig = this.#keyVersions.get(key);
9
- if (!sig) {
10
- const inner = createSignal(0);
11
- this.#keyVersions.set(key, inner);
12
- sig = inner;
13
- }
14
- return sig;
15
- }
16
- #bumpKey(key: K) {
17
- const sig = this.#keyVersions.get(key);
18
- if (sig) {
19
- const v = sig.peek() + 1;
20
- (sig as Signal<number>).set(v);
21
- }
22
- }
23
- #bumpStruct() {
24
- this.#structVal++;
25
- this.#structVersion.set(this.#structVal);
26
- }
27
-
28
- constructor(entries?: readonly (readonly [K, V])[] | null) {
29
- super(entries);
30
- this.#structVersion = createSignal(0);
31
- if (entries) {
32
- for (const [k] of entries) this.#getKeyVersion(k);
33
- }
34
- }
35
-
36
- get(key: K): V | undefined {
37
- this.#getKeyVersion(key)();
38
- return super.get(key);
39
- }
40
-
41
- set(key: K, value: V): this {
42
- const existed = super.has(key);
43
- super.set(key, value);
44
- this.#bumpKey(key);
45
- if (!existed) this.#bumpStruct();
46
- return this;
47
- }
48
-
49
- delete(key: K): boolean {
50
- const result = super.delete(key);
51
- if (result) {
52
- this.#bumpKey(key);
53
- this.#bumpStruct();
54
- }
55
- return result;
56
- }
57
-
58
- clear(): void {
59
- if (this.size > 0) {
60
- for (const key of this.keys()) this.#bumpKey(key);
61
- super.clear();
62
- this.#bumpStruct();
63
- }
64
- }
65
-
66
- forEach(
67
- callbackfn: (value: V, key: K, map: Map<K, V>) => void,
68
- thisArg?: unknown,
69
- ): void {
70
- this.#structVersion();
71
- super.forEach(callbackfn, thisArg);
72
- }
73
-
74
- get size(): number {
75
- this.#structVersion();
76
- return super.size;
77
- }
78
-
79
- entries(): IterableIterator<[K, V]> {
80
- this.#structVersion();
81
- return super.entries();
82
- }
83
-
84
- keys(): IterableIterator<K> {
85
- this.#structVersion();
86
- return super.keys();
87
- }
88
-
89
- values(): IterableIterator<V> {
90
- this.#structVersion();
91
- return super.values();
92
- }
93
-
94
- [Symbol.iterator](): IterableIterator<[K, V]> {
95
- this.#structVersion();
96
- return super[Symbol.iterator]();
97
- }
98
- }
1
+ import { createSignal, type Signal } from "../index.ts";
2
+
3
+ export class ReactiveMap<K, V> extends Map<K, V> {
4
+ #keyVersions: Map<K, Signal<number>> = new Map();
5
+ #structVersion: Signal<number>;
6
+ #structVal: number = 0;
7
+ #getKeyVersion(key: K): Signal<number> {
8
+ let sig = this.#keyVersions.get(key);
9
+ if (!sig) {
10
+ const inner = createSignal(0);
11
+ this.#keyVersions.set(key, inner);
12
+ sig = inner;
13
+ }
14
+ return sig;
15
+ }
16
+ #bumpKey(key: K) {
17
+ const sig = this.#keyVersions.get(key);
18
+ if (sig) {
19
+ const v = sig.peek() + 1;
20
+ (sig as Signal<number>).set(v);
21
+ }
22
+ }
23
+ #bumpStruct() {
24
+ this.#structVal++;
25
+ this.#structVersion.set(this.#structVal);
26
+ }
27
+
28
+ constructor(entries?: readonly (readonly [K, V])[] | null) {
29
+ super(entries);
30
+ this.#structVersion = createSignal(0);
31
+ if (entries) {
32
+ for (const [k] of entries) this.#getKeyVersion(k);
33
+ }
34
+ }
35
+
36
+ get(key: K): V | undefined {
37
+ this.#getKeyVersion(key)();
38
+ return super.get(key);
39
+ }
40
+
41
+ set(key: K, value: V): this {
42
+ const existed = super.has(key);
43
+ super.set(key, value);
44
+ this.#bumpKey(key);
45
+ if (!existed) this.#bumpStruct();
46
+ return this;
47
+ }
48
+
49
+ delete(key: K): boolean {
50
+ const result = super.delete(key);
51
+ if (result) {
52
+ this.#bumpKey(key);
53
+ this.#bumpStruct();
54
+ }
55
+ return result;
56
+ }
57
+
58
+ clear(): void {
59
+ if (this.size > 0) {
60
+ for (const key of this.keys()) this.#bumpKey(key);
61
+ super.clear();
62
+ this.#bumpStruct();
63
+ }
64
+ }
65
+
66
+ forEach(
67
+ callbackfn: (value: V, key: K, map: Map<K, V>) => void,
68
+ thisArg?: unknown,
69
+ ): void {
70
+ this.#structVersion();
71
+ super.forEach(callbackfn, thisArg);
72
+ }
73
+
74
+ get size(): number {
75
+ this.#structVersion();
76
+ return super.size;
77
+ }
78
+
79
+ entries(): IterableIterator<[K, V]> {
80
+ this.#structVersion();
81
+ return super.entries();
82
+ }
83
+
84
+ keys(): IterableIterator<K> {
85
+ this.#structVersion();
86
+ return super.keys();
87
+ }
88
+
89
+ values(): IterableIterator<V> {
90
+ this.#structVersion();
91
+ return super.values();
92
+ }
93
+
94
+ [Symbol.iterator](): IterableIterator<[K, V]> {
95
+ this.#structVersion();
96
+ return super[Symbol.iterator]();
97
+ }
98
+ }
package/reactivity/set.ts CHANGED
@@ -1,74 +1,74 @@
1
- import { createSignal, type Signal } from "../index.ts";
2
-
3
- export class ReactiveSet<T> extends Set<T> {
4
- #version: Signal<number>;
5
- #versionVal: number = 0;
6
-
7
- constructor(values?: readonly T[] | null) {
8
- super(values);
9
- this.#version = createSignal(0);
10
- }
11
-
12
- #bump() {
13
- this.#versionVal++;
14
- this.#version.set(this.#versionVal);
15
- }
16
-
17
- has(value: T): boolean {
18
- this.#version();
19
- return super.has(value);
20
- }
21
-
22
- add(value: T): this {
23
- const sizeBefore = super.size;
24
- super.add(value);
25
- if (super.size !== sizeBefore) this.#bump();
26
- return this;
27
- }
28
-
29
- delete(value: T): boolean {
30
- const result = super.delete(value);
31
- if (result) this.#bump();
32
- return result;
33
- }
34
-
35
- clear(): void {
36
- if (this.size > 0) {
37
- super.clear();
38
- this.#bump();
39
- }
40
- }
41
-
42
- forEach(
43
- callbackfn: (value: T, value2: T, set: Set<T>) => void,
44
- thisArg?: unknown,
45
- ): void {
46
- this.#version();
47
- super.forEach(callbackfn, thisArg);
48
- }
49
-
50
- get size(): number {
51
- this.#version();
52
- return super.size;
53
- }
54
-
55
- entries(): IterableIterator<[T, T]> {
56
- this.#version();
57
- return super.entries();
58
- }
59
-
60
- keys(): IterableIterator<T> {
61
- this.#version();
62
- return super.keys();
63
- }
64
-
65
- values(): IterableIterator<T> {
66
- this.#version();
67
- return super.values();
68
- }
69
-
70
- [Symbol.iterator](): IterableIterator<T> {
71
- this.#version();
72
- return super[Symbol.iterator]();
73
- }
74
- }
1
+ import { createSignal, type Signal } from "../index.ts";
2
+
3
+ export class ReactiveSet<T> extends Set<T> {
4
+ #version: Signal<number>;
5
+ #versionVal: number = 0;
6
+
7
+ constructor(values?: readonly T[] | null) {
8
+ super(values);
9
+ this.#version = createSignal(0);
10
+ }
11
+
12
+ #bump() {
13
+ this.#versionVal++;
14
+ this.#version.set(this.#versionVal);
15
+ }
16
+
17
+ has(value: T): boolean {
18
+ this.#version();
19
+ return super.has(value);
20
+ }
21
+
22
+ add(value: T): this {
23
+ const sizeBefore = super.size;
24
+ super.add(value);
25
+ if (super.size !== sizeBefore) this.#bump();
26
+ return this;
27
+ }
28
+
29
+ delete(value: T): boolean {
30
+ const result = super.delete(value);
31
+ if (result) this.#bump();
32
+ return result;
33
+ }
34
+
35
+ clear(): void {
36
+ if (this.size > 0) {
37
+ super.clear();
38
+ this.#bump();
39
+ }
40
+ }
41
+
42
+ forEach(
43
+ callbackfn: (value: T, value2: T, set: Set<T>) => void,
44
+ thisArg?: unknown,
45
+ ): void {
46
+ this.#version();
47
+ super.forEach(callbackfn, thisArg);
48
+ }
49
+
50
+ get size(): number {
51
+ this.#version();
52
+ return super.size;
53
+ }
54
+
55
+ entries(): IterableIterator<[T, T]> {
56
+ this.#version();
57
+ return super.entries();
58
+ }
59
+
60
+ keys(): IterableIterator<T> {
61
+ this.#version();
62
+ return super.keys();
63
+ }
64
+
65
+ values(): IterableIterator<T> {
66
+ this.#version();
67
+ return super.values();
68
+ }
69
+
70
+ [Symbol.iterator](): IterableIterator<T> {
71
+ this.#version();
72
+ return super[Symbol.iterator]();
73
+ }
74
+ }
package/test-preload.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { Window } from "happy-dom";
2
-
3
- const window = new Window();
4
- (globalThis as any).document = window.document;
5
- (globalThis as any).Element = window.Element;
6
- (globalThis as any).Text = window.Text;
7
- (globalThis as any).Node = window.Node;
8
- (globalThis as any).HTMLElement = window.HTMLElement;
9
- (globalThis as any).Comment = window.Comment;
1
+ import { Window } from "happy-dom";
2
+
3
+ const window = new Window();
4
+ (globalThis as any).document = window.document;
5
+ (globalThis as any).Element = window.Element;
6
+ (globalThis as any).Text = window.Text;
7
+ (globalThis as any).Node = window.Node;
8
+ (globalThis as any).HTMLElement = window.HTMLElement;
9
+ (globalThis as any).Comment = window.Comment;
package/tsconfig.json CHANGED
@@ -1,30 +1,30 @@
1
- {
2
- "compilerOptions": {
3
- // Environment setup & latest features
4
- "lib": ["ESNext", "DOM"],
5
- "target": "ESNext",
6
- "module": "Preserve",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
- "types": ["bun"],
11
-
12
- // Bundler mode
13
- "moduleResolution": "bundler",
14
- "allowImportingTsExtensions": true,
15
- "verbatimModuleSyntax": true,
16
- "noEmit": true,
17
-
18
- // Best practices
19
- "strict": true,
20
- "skipLibCheck": true,
21
- "noFallthroughCasesInSwitch": true,
22
- "noUncheckedIndexedAccess": true,
23
- "noImplicitOverride": true,
24
-
25
- // Some stricter flags (disabled by default)
26
- "noUnusedLocals": false,
27
- "noUnusedParameters": false,
28
- "noPropertyAccessFromIndexSignature": false
29
- }
30
- }
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext", "DOM"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+ "types": ["bun"],
11
+
12
+ // Bundler mode
13
+ "moduleResolution": "bundler",
14
+ "allowImportingTsExtensions": true,
15
+ "verbatimModuleSyntax": true,
16
+ "noEmit": true,
17
+
18
+ // Best practices
19
+ "strict": true,
20
+ "skipLibCheck": true,
21
+ "noFallthroughCasesInSwitch": true,
22
+ "noUncheckedIndexedAccess": true,
23
+ "noImplicitOverride": true,
24
+
25
+ // Some stricter flags (disabled by default)
26
+ "noUnusedLocals": false,
27
+ "noUnusedParameters": false,
28
+ "noPropertyAccessFromIndexSignature": false
29
+ }
30
+ }