@takazudo/zfb 4.4.0 → 4.5.0

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.
Files changed (38) hide show
  1. package/README.md +14 -0
  2. package/dist/css.d.ts +45 -0
  3. package/dist/css.js +137 -0
  4. package/dist/css.js.map +1 -0
  5. package/dist/zudo-react/dom-bindings.js +11 -5
  6. package/dist/zudo-react/dom-bindings.js.map +1 -1
  7. package/dist/zudo-react/error-boundary-client.d.ts +3 -0
  8. package/dist/zudo-react/error-boundary-client.js +232 -0
  9. package/dist/zudo-react/error-boundary-client.js.map +1 -0
  10. package/dist/zudo-react/error-boundary-type.d.ts +8 -0
  11. package/dist/zudo-react/error-boundary-type.js +25 -0
  12. package/dist/zudo-react/error-boundary-type.js.map +1 -0
  13. package/dist/zudo-react/error-boundary.d.ts +8 -0
  14. package/dist/zudo-react/error-boundary.js +13 -0
  15. package/dist/zudo-react/error-boundary.js.map +1 -0
  16. package/dist/zudo-react/form-recovery.d.ts +2 -0
  17. package/dist/zudo-react/form-recovery.js +116 -0
  18. package/dist/zudo-react/form-recovery.js.map +1 -0
  19. package/dist/zudo-react/forms.d.ts +38 -4
  20. package/dist/zudo-react/forms.js +143 -172
  21. package/dist/zudo-react/forms.js.map +1 -1
  22. package/dist/zudo-react/hydrate.d.ts +68 -0
  23. package/dist/zudo-react/hydrate.js +177 -89
  24. package/dist/zudo-react/hydrate.js.map +1 -1
  25. package/dist/zudo-react/index.d.ts +1 -0
  26. package/dist/zudo-react/index.js +1 -0
  27. package/dist/zudo-react/index.js.map +1 -1
  28. package/dist/zudo-react/render-html.js +55 -10
  29. package/dist/zudo-react/render-html.js.map +1 -1
  30. package/dist/zudo-react/scope.d.ts +21 -13
  31. package/dist/zudo-react/scope.js +141 -113
  32. package/dist/zudo-react/scope.js.map +1 -1
  33. package/dist/zudo-react/style.d.ts +0 -1
  34. package/dist/zudo-react/style.js +11 -503
  35. package/dist/zudo-react/style.js.map +1 -1
  36. package/dist/zudo-react/vocabulary.js +12 -49
  37. package/dist/zudo-react/vocabulary.js.map +1 -1
  38. package/package.json +11 -7
@@ -9,17 +9,8 @@ function isPromise(value) {
9
9
  }
10
10
  export class RuntimeScope {
11
11
  id = ++nextScopeId;
12
- component;
13
- parent;
14
- reporter;
15
- path;
16
- protocol;
17
- build;
18
- children = [];
12
+ children = new Set();
19
13
  cleanups = [];
20
- activations = [];
21
- effects = [];
22
- controller;
23
14
  live = true;
24
15
  activated = false;
25
16
  jobReporter = (code, actual) => {
@@ -35,7 +26,7 @@ export class RuntimeScope {
35
26
  this.path = options.path ?? options.parent?.path ?? "";
36
27
  this.protocol = options.protocol ?? options.parent?.protocol ?? "zudo-react.v1";
37
28
  this.build = options.build ?? options.parent?.build ?? "";
38
- this.parent?.children.push(this);
29
+ this.parent?.children.add(this);
39
30
  }
40
31
  get active() {
41
32
  return this.live;
@@ -43,16 +34,6 @@ export class RuntimeScope {
43
34
  get isActivated() {
44
35
  return this.activated;
45
36
  }
46
- get abortSignal() {
47
- this.controller ??= new AbortController();
48
- if (!this.live && !this.controller.signal.aborted)
49
- this.controller.abort();
50
- return this.controller.signal;
51
- }
52
- ensureSetup() {
53
- if (!this.live || this.activated || currentScope !== this)
54
- throw new Error("ZR_SCOPE_SETUP: registration requires active setup");
55
- }
56
37
  report(code, phase, actual) {
57
38
  const stack = [];
58
39
  for (let scope = this; scope; scope = scope.parent)
@@ -74,80 +55,24 @@ export class RuntimeScope {
74
55
  /* Reporter failures must not stop resource cleanup. */
75
56
  }
76
57
  }
77
- onCleanup(fn) {
78
- this.ensureSetup();
79
- this.cleanups.push(fn);
80
- }
81
- onActivate(fn) {
82
- this.ensureSetup();
83
- this.activations.push(fn);
84
- }
85
- effect(fn) {
86
- this.ensureSetup();
87
- let cleanup;
88
- const subscription = subscribe(() => {
89
- if (cleanup) {
90
- try {
91
- const result = untracked(cleanup);
92
- if (isPromise(result))
93
- this.report("ZR_ASYNC_CLEANUP", "cleanup", "effect cleanup returned a promise");
94
- }
95
- catch (error) {
96
- this.report("ZR_EFFECT_CLEANUP", "cleanup", String(error));
97
- }
98
- cleanup = undefined;
99
- }
100
- try {
101
- const result = fn();
102
- if (isPromise(result))
103
- this.report("ZR_ASYNC_CLEANUP", "update", "effect returned a promise");
104
- else if (typeof result === "function")
105
- cleanup = result;
106
- }
107
- catch (error) {
108
- this.report("ZR_EFFECT_ERROR", "update", String(error));
109
- }
110
- }, {
111
- phase: "effect",
112
- id: `${this.component}:effect:${this.id}:${this.effects.length}`,
113
- active: () => this.live && this.activated,
114
- report: this.root().jobReporter,
115
- });
116
- const job = {
117
- id: subscription.id,
118
- phase: "effect",
119
- active: () => this.live && this.activated,
120
- run: () => subscription.run(),
121
- report: this.root().jobReporter,
122
- };
123
- this.effects.push({
124
- start: () => enqueue(job),
125
- dispose: () => {
126
- subscription.dispose();
127
- if (cleanup) {
128
- try {
129
- const result = untracked(cleanup);
130
- if (isPromise(result))
131
- this.report("ZR_ASYNC_CLEANUP", "cleanup", "effect cleanup returned a promise");
132
- }
133
- catch (error) {
134
- this.report("ZR_EFFECT_CLEANUP", "cleanup", String(error));
135
- }
136
- cleanup = undefined;
137
- }
138
- },
139
- });
140
- }
141
58
  child(component) {
142
59
  if (!this.live)
143
60
  throw new Error("ZR_SCOPE_DISPOSED");
144
- return new RuntimeScope({ component, parent: this });
61
+ const child = new RuntimeScope({ component, parent: this });
62
+ this.expose?.(child);
63
+ return child;
64
+ }
65
+ // The optional service prepares under a catch; commit/activation stays outside it.
66
+ recoverRender(error) {
67
+ const commit = this.root().recovery?.(this, error);
68
+ commit?.();
69
+ return !!commit;
145
70
  }
146
71
  activate() {
147
72
  if (!this.live || this.activated)
148
73
  return;
149
74
  try {
150
- for (const child of this.children)
75
+ for (const child of [...this.children])
151
76
  child.activate();
152
77
  }
153
78
  catch (error) {
@@ -155,50 +80,34 @@ export class RuntimeScope {
155
80
  throw error;
156
81
  }
157
82
  this.activated = true;
158
- for (const fn of this.activations) {
159
- try {
160
- const result = fn();
161
- if (isPromise(result))
162
- throw new Error("ZR_ASYNC_CLEANUP: activation returned a promise");
163
- if (typeof result === "function")
164
- this.cleanups.push(result);
165
- }
166
- catch (error) {
167
- this.report("ZR_ACTIVATION_ERROR", "activation", String(error));
168
- this.dispose();
169
- throw error;
170
- }
171
- }
172
- for (const effect of this.effects)
173
- effect.start();
83
+ this.start?.();
174
84
  }
175
85
  dispose() {
176
86
  if (!this.live)
177
87
  return;
178
88
  this.live = false;
89
+ this.parent?.children.delete(this);
90
+ this.renderRecovery = undefined;
91
+ this.recovery = undefined;
179
92
  this.controller?.abort();
180
93
  for (const child of [...this.children].reverse())
181
94
  child.dispose();
182
- this.children.length = 0;
183
- for (const effect of this.effects)
184
- effect.dispose();
185
- this.effects.length = 0;
95
+ this.children.clear();
96
+ this.stop?.();
186
97
  for (const cleanup of [...this.cleanups].reverse()) {
187
98
  try {
188
- const result = untracked(cleanup);
189
- if (isPromise(result))
190
- this.report("ZR_ASYNC_CLEANUP", "cleanup", "cleanup returned a promise");
99
+ untracked(cleanup);
191
100
  }
192
101
  catch (error) {
193
102
  this.report("ZR_CLEANUP_ERROR", "cleanup", String(error));
194
103
  }
195
104
  }
196
105
  this.cleanups.length = 0;
197
- this.activations.length = 0;
198
106
  }
199
107
  }
200
108
  export function createScope(options) {
201
- return new RuntimeScope(options);
109
+ const scope = new RuntimeScope(options);
110
+ return exposeScope(scope);
202
111
  }
203
112
  export function withScope(scope, fn) {
204
113
  if (!scope.active)
@@ -215,6 +124,125 @@ export function withScope(scope, fn) {
215
124
  export function getScope() {
216
125
  if (!currentScope || !currentScope.active || currentScope.isActivated)
217
126
  throw new Error("ZR_NO_SCOPE: getScope requires synchronous setup");
218
- return currentScope;
127
+ return exposeScope(currentScope);
128
+ }
129
+ function effect(fn) {
130
+ ensureSetup(this);
131
+ let cleanup;
132
+ const subscription = subscribe(() => {
133
+ if (cleanup) {
134
+ try {
135
+ const result = untracked(cleanup);
136
+ if (isPromise(result))
137
+ this.report("ZR_ASYNC_CLEANUP", "cleanup", "effect cleanup returned a promise");
138
+ }
139
+ catch (error) {
140
+ this.report("ZR_EFFECT_CLEANUP", "cleanup", String(error));
141
+ }
142
+ cleanup = undefined;
143
+ }
144
+ try {
145
+ const result = fn();
146
+ if (isPromise(result))
147
+ this.report("ZR_ASYNC_CLEANUP", "update", "effect returned a promise");
148
+ else if (typeof result === "function")
149
+ cleanup = result;
150
+ }
151
+ catch (error) {
152
+ this.report("ZR_EFFECT_ERROR", "update", String(error));
153
+ }
154
+ }, {
155
+ phase: "effect",
156
+ id: `${this.component}:effect:${this.id}:${this.effects.length}`,
157
+ active: () => this.live && this.activated,
158
+ report: this.root().jobReporter,
159
+ });
160
+ const job = {
161
+ id: subscription.id,
162
+ phase: "effect",
163
+ active: () => this.live && this.activated,
164
+ run: () => subscription.run(),
165
+ report: this.root().jobReporter,
166
+ };
167
+ this.effects.push({
168
+ start: () => enqueue(job),
169
+ dispose: () => {
170
+ subscription.dispose();
171
+ if (cleanup) {
172
+ try {
173
+ const result = untracked(cleanup);
174
+ if (isPromise(result))
175
+ this.report("ZR_ASYNC_CLEANUP", "cleanup", "effect cleanup returned a promise");
176
+ }
177
+ catch (error) {
178
+ this.report("ZR_EFFECT_CLEANUP", "cleanup", String(error));
179
+ }
180
+ cleanup = undefined;
181
+ }
182
+ },
183
+ });
184
+ }
185
+ // Public lifecycle capabilities are installed only when application code asks
186
+ // for a scope. Internal renderer scopes keep the same ownership lifecycle.
187
+ function exposeScope(scope) {
188
+ if (!scope.expose) {
189
+ scope.expose = exposeScope;
190
+ scope.effects = [];
191
+ scope.activations = [];
192
+ scope.stop = () => {
193
+ for (const effect of scope.effects)
194
+ effect.dispose();
195
+ scope.effects.length = 0;
196
+ scope.activations.length = 0;
197
+ };
198
+ scope.effect = effect;
199
+ scope.onActivate = onActivate;
200
+ scope.onCleanup = onCleanup;
201
+ scope.start = activateCallbacks.bind(scope);
202
+ Object.defineProperty(scope, "abortSignal", { get: abortSignal });
203
+ }
204
+ return scope;
205
+ }
206
+ function abortSignal() {
207
+ this.controller ??= new AbortController();
208
+ if (!this.live && !this.controller.signal.aborted)
209
+ this.controller.abort();
210
+ return this.controller.signal;
211
+ }
212
+ function onActivate(fn) {
213
+ ensureSetup(this);
214
+ this.activations.push(fn);
215
+ }
216
+ function activateCallbacks() {
217
+ for (const fn of this.activations) {
218
+ try {
219
+ const result = fn();
220
+ if (isPromise(result))
221
+ throw new Error("ZR_ASYNC_CLEANUP: activation returned a promise");
222
+ if (typeof result === "function")
223
+ registerCleanup(this, result);
224
+ }
225
+ catch (error) {
226
+ this.report("ZR_ACTIVATION_ERROR", "activation", String(error));
227
+ this.dispose();
228
+ throw error;
229
+ }
230
+ }
231
+ for (const effect of this.effects)
232
+ effect.start();
233
+ }
234
+ function ensureSetup(scope) {
235
+ if (!scope.live || scope.activated || currentScope !== scope)
236
+ throw new Error("ZR_SCOPE_SETUP: registration requires active setup");
237
+ }
238
+ function onCleanup(fn) {
239
+ ensureSetup(this);
240
+ registerCleanup(this, fn);
241
+ }
242
+ function registerCleanup(scope, fn) {
243
+ scope.cleanups.push(() => {
244
+ if (isPromise(fn()))
245
+ scope.report("ZR_ASYNC_CLEANUP", "cleanup", "cleanup returned a promise");
246
+ });
219
247
  }
220
248
  //# sourceMappingURL=scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/zudo-react/scope.ts"],"names":[],"mappings":"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","sourcesContent":["import { subscribe, untracked, type Subscription } from \"./reactive.js\";\nimport { enqueue, type Job } from \"./scheduler.js\";\nimport type { Cleanup, Diagnostic, Reporter, Scope } from \"./index.js\";\n\nlet currentScope: RuntimeScope | null = null;\nlet nextScopeId = 0;\n\nfunction isPromise(value: unknown): value is PromiseLike<unknown> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\nexport interface ScopeOptions {\n component: string;\n reporter?: Reporter;\n parent?: RuntimeScope;\n path?: string;\n protocol?: string;\n build?: string;\n}\n\nexport class RuntimeScope implements Scope {\n readonly id = ++nextScopeId;\n readonly component: string;\n readonly parent: RuntimeScope | undefined;\n private readonly reporter: Reporter | undefined;\n private readonly path: string;\n private readonly protocol: string;\n private readonly build: string;\n private readonly children: RuntimeScope[] = [];\n private readonly cleanups: Cleanup[] = [];\n private readonly activations: Array<() => void | Cleanup> = [];\n private readonly effects: Array<{ start: () => void; dispose: () => void }> = [];\n private controller: AbortController | undefined;\n private live = true;\n private activated = false;\n private readonly jobReporter = (code: string, actual: string): void => {\n this.report(code, \"update\", actual);\n };\n private root(): RuntimeScope {\n return this.parent?.root() ?? this;\n }\n\n constructor(options: ScopeOptions) {\n this.component = options.component;\n this.parent = options.parent;\n this.reporter = options.reporter ?? options.parent?.reporter;\n this.path = options.path ?? options.parent?.path ?? \"\";\n this.protocol = options.protocol ?? options.parent?.protocol ?? \"zudo-react.v1\";\n this.build = options.build ?? options.parent?.build ?? \"\";\n this.parent?.children.push(this);\n }\n get active(): boolean {\n return this.live;\n }\n get isActivated(): boolean {\n return this.activated;\n }\n get abortSignal(): AbortSignal {\n this.controller ??= new AbortController();\n if (!this.live && !this.controller.signal.aborted) this.controller.abort();\n return this.controller.signal;\n }\n private ensureSetup(): void {\n if (!this.live || this.activated || currentScope !== this)\n throw new Error(\"ZR_SCOPE_SETUP: registration requires active setup\");\n }\n report(code: string, phase: Diagnostic[\"phase\"], actual: string): void {\n const stack: string[] = [];\n for (let scope: RuntimeScope | undefined = this; scope; scope = scope.parent)\n stack.unshift(scope.component);\n try {\n this.reporter?.({\n code,\n phase,\n component: this.component,\n componentStack: stack,\n path: this.path,\n expected: \"\",\n actual,\n protocol: this.protocol,\n build: this.build,\n });\n } catch {\n /* Reporter failures must not stop resource cleanup. */\n }\n }\n onCleanup(fn: Cleanup): void {\n this.ensureSetup();\n this.cleanups.push(fn);\n }\n onActivate(fn: () => void | Cleanup): void {\n this.ensureSetup();\n this.activations.push(fn);\n }\n effect(fn: () => void | Cleanup): void {\n this.ensureSetup();\n let cleanup: Cleanup | undefined;\n const subscription: Subscription = subscribe(\n () => {\n if (cleanup) {\n try {\n const result: unknown = untracked(cleanup);\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"cleanup\", \"effect cleanup returned a promise\");\n } catch (error) {\n this.report(\"ZR_EFFECT_CLEANUP\", \"cleanup\", String(error));\n }\n cleanup = undefined;\n }\n try {\n const result = fn();\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"update\", \"effect returned a promise\");\n else if (typeof result === \"function\") cleanup = result;\n } catch (error) {\n this.report(\"ZR_EFFECT_ERROR\", \"update\", String(error));\n }\n },\n {\n phase: \"effect\",\n id: `${this.component}:effect:${this.id}:${this.effects.length}`,\n active: () => this.live && this.activated,\n report: this.root().jobReporter,\n },\n );\n const job: Job = {\n id: subscription.id,\n phase: \"effect\",\n active: () => this.live && this.activated,\n run: () => subscription.run(),\n report: this.root().jobReporter,\n };\n this.effects.push({\n start: () => enqueue(job),\n dispose: () => {\n subscription.dispose();\n if (cleanup) {\n try {\n const result: unknown = untracked(cleanup);\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"cleanup\", \"effect cleanup returned a promise\");\n } catch (error) {\n this.report(\"ZR_EFFECT_CLEANUP\", \"cleanup\", String(error));\n }\n cleanup = undefined;\n }\n },\n });\n }\n child(component: string): RuntimeScope {\n if (!this.live) throw new Error(\"ZR_SCOPE_DISPOSED\");\n return new RuntimeScope({ component, parent: this });\n }\n activate(): void {\n if (!this.live || this.activated) return;\n try {\n for (const child of this.children) child.activate();\n } catch (error) {\n this.dispose();\n throw error;\n }\n this.activated = true;\n for (const fn of this.activations) {\n try {\n const result = fn();\n if (isPromise(result)) throw new Error(\"ZR_ASYNC_CLEANUP: activation returned a promise\");\n if (typeof result === \"function\") this.cleanups.push(result);\n } catch (error) {\n this.report(\"ZR_ACTIVATION_ERROR\", \"activation\", String(error));\n this.dispose();\n throw error;\n }\n }\n for (const effect of this.effects) effect.start();\n }\n dispose(): void {\n if (!this.live) return;\n this.live = false;\n this.controller?.abort();\n for (const child of [...this.children].reverse()) child.dispose();\n this.children.length = 0;\n for (const effect of this.effects) effect.dispose();\n this.effects.length = 0;\n for (const cleanup of [...this.cleanups].reverse()) {\n try {\n const result: unknown = untracked(cleanup);\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"cleanup\", \"cleanup returned a promise\");\n } catch (error) {\n this.report(\"ZR_CLEANUP_ERROR\", \"cleanup\", String(error));\n }\n }\n this.cleanups.length = 0;\n this.activations.length = 0;\n }\n}\n\nexport function createScope(options: ScopeOptions): RuntimeScope {\n return new RuntimeScope(options);\n}\nexport function withScope<T>(scope: RuntimeScope, fn: () => T): T {\n if (!scope.active) throw new Error(\"ZR_SCOPE_DISPOSED\");\n const previous = currentScope;\n currentScope = scope;\n try {\n return fn();\n } finally {\n currentScope = previous;\n }\n}\nexport function getScope(): Scope {\n if (!currentScope || !currentScope.active || currentScope.isActivated)\n throw new Error(\"ZR_NO_SCOPE: getScope requires synchronous setup\");\n return currentScope;\n}\n"]}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/zudo-react/scope.ts"],"names":[],"mappings":"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","sourcesContent":["import { subscribe, untracked, type Subscription } from \"./reactive.js\";\nimport { enqueue, type Job } from \"./scheduler.js\";\nimport type { Cleanup, Diagnostic, Reporter, Scope } from \"./index.js\";\n\nlet currentScope: RuntimeScope | null = null;\nlet nextScopeId = 0;\n\nfunction isPromise(value: unknown): value is PromiseLike<unknown> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\nexport interface ScopeOptions {\n component: string;\n reporter?: Reporter;\n parent?: RuntimeScope;\n path?: string;\n protocol?: string;\n build?: string;\n}\n\nexport class RuntimeScope implements Scope {\n readonly id = ++nextScopeId;\n declare readonly component: string;\n declare readonly parent: RuntimeScope | undefined;\n declare private readonly reporter: Reporter | undefined;\n declare private readonly path: string;\n declare private readonly protocol: string;\n declare private readonly build: string;\n private readonly children = new Set<RuntimeScope>();\n readonly cleanups: Cleanup[] = [];\n declare activations: Array<() => void | Cleanup>;\n declare effects: Array<{ start: () => void; dispose: () => void }>;\n declare expose?: (scope: RuntimeScope) => RuntimeScope;\n declare start?: () => void;\n declare stop?: () => void;\n declare recovery: ((scope: RuntimeScope, error: unknown) => (() => void) | undefined) | undefined;\n declare renderRecovery: ((error: unknown) => () => void) | undefined;\n declare controller: AbortController | undefined;\n live = true;\n activated = false;\n readonly jobReporter = (code: string, actual: string): void => {\n this.report(code, \"update\", actual);\n };\n root(): RuntimeScope {\n return this.parent?.root() ?? this;\n }\n\n constructor(options: ScopeOptions) {\n this.component = options.component;\n this.parent = options.parent;\n this.reporter = options.reporter ?? options.parent?.reporter;\n this.path = options.path ?? options.parent?.path ?? \"\";\n this.protocol = options.protocol ?? options.parent?.protocol ?? \"zudo-react.v1\";\n this.build = options.build ?? options.parent?.build ?? \"\";\n this.parent?.children.add(this);\n }\n get active(): boolean {\n return this.live;\n }\n get isActivated(): boolean {\n return this.activated;\n }\n declare readonly abortSignal: AbortSignal;\n report(code: string, phase: Diagnostic[\"phase\"], actual: string): void {\n const stack: string[] = [];\n for (let scope: RuntimeScope | undefined = this; scope; scope = scope.parent)\n stack.unshift(scope.component);\n try {\n this.reporter?.({\n code,\n phase,\n component: this.component,\n componentStack: stack,\n path: this.path,\n expected: \"\",\n actual,\n protocol: this.protocol,\n build: this.build,\n });\n } catch {\n /* Reporter failures must not stop resource cleanup. */\n }\n }\n declare onCleanup: Scope[\"onCleanup\"];\n declare onActivate: Scope[\"onActivate\"];\n declare effect: Scope[\"effect\"];\n child(component: string): RuntimeScope {\n if (!this.live) throw new Error(\"ZR_SCOPE_DISPOSED\");\n const child = new RuntimeScope({ component, parent: this });\n this.expose?.(child);\n return child;\n }\n // The optional service prepares under a catch; commit/activation stays outside it.\n recoverRender(error: unknown): boolean {\n const commit = this.root().recovery?.(this, error);\n commit?.();\n return !!commit;\n }\n activate(): void {\n if (!this.live || this.activated) return;\n try {\n for (const child of [...this.children]) child.activate();\n } catch (error) {\n this.dispose();\n throw error;\n }\n this.activated = true;\n this.start?.();\n }\n dispose(): void {\n if (!this.live) return;\n this.live = false;\n this.parent?.children.delete(this);\n this.renderRecovery = undefined;\n this.recovery = undefined;\n this.controller?.abort();\n for (const child of [...this.children].reverse()) child.dispose();\n this.children.clear();\n this.stop?.();\n for (const cleanup of [...this.cleanups].reverse()) {\n try {\n untracked(cleanup);\n } catch (error) {\n this.report(\"ZR_CLEANUP_ERROR\", \"cleanup\", String(error));\n }\n }\n this.cleanups.length = 0;\n }\n}\n\nexport function createScope(options: ScopeOptions): RuntimeScope {\n const scope = new RuntimeScope(options);\n return exposeScope(scope);\n}\nexport function withScope<T>(scope: RuntimeScope, fn: () => T): T {\n if (!scope.active) throw new Error(\"ZR_SCOPE_DISPOSED\");\n const previous = currentScope;\n currentScope = scope;\n try {\n return fn();\n } finally {\n currentScope = previous;\n }\n}\nexport function getScope(): Scope {\n if (!currentScope || !currentScope.active || currentScope.isActivated)\n throw new Error(\"ZR_NO_SCOPE: getScope requires synchronous setup\");\n return exposeScope(currentScope);\n}\n\nfunction effect(this: RuntimeScope, fn: () => void | Cleanup): void {\n ensureSetup(this);\n let cleanup: Cleanup | undefined;\n const subscription: Subscription = subscribe(\n () => {\n if (cleanup) {\n try {\n const result: unknown = untracked(cleanup);\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"cleanup\", \"effect cleanup returned a promise\");\n } catch (error) {\n this.report(\"ZR_EFFECT_CLEANUP\", \"cleanup\", String(error));\n }\n cleanup = undefined;\n }\n try {\n const result = fn();\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"update\", \"effect returned a promise\");\n else if (typeof result === \"function\") cleanup = result;\n } catch (error) {\n this.report(\"ZR_EFFECT_ERROR\", \"update\", String(error));\n }\n },\n {\n phase: \"effect\",\n id: `${this.component}:effect:${this.id}:${this.effects.length}`,\n active: () => this.live && this.activated,\n report: this.root().jobReporter,\n },\n );\n const job: Job = {\n id: subscription.id,\n phase: \"effect\",\n active: () => this.live && this.activated,\n run: () => subscription.run(),\n report: this.root().jobReporter,\n };\n this.effects.push({\n start: () => enqueue(job),\n dispose: () => {\n subscription.dispose();\n if (cleanup) {\n try {\n const result: unknown = untracked(cleanup);\n if (isPromise(result))\n this.report(\"ZR_ASYNC_CLEANUP\", \"cleanup\", \"effect cleanup returned a promise\");\n } catch (error) {\n this.report(\"ZR_EFFECT_CLEANUP\", \"cleanup\", String(error));\n }\n cleanup = undefined;\n }\n },\n });\n}\n\n// Public lifecycle capabilities are installed only when application code asks\n// for a scope. Internal renderer scopes keep the same ownership lifecycle.\nfunction exposeScope(scope: RuntimeScope): RuntimeScope {\n if (!scope.expose) {\n scope.expose = exposeScope;\n scope.effects = [];\n scope.activations = [];\n scope.stop = () => {\n for (const effect of scope.effects) effect.dispose();\n scope.effects.length = 0;\n scope.activations.length = 0;\n };\n scope.effect = effect;\n scope.onActivate = onActivate;\n scope.onCleanup = onCleanup;\n scope.start = activateCallbacks.bind(scope);\n Object.defineProperty(scope, \"abortSignal\", { get: abortSignal });\n }\n return scope;\n}\nfunction abortSignal(this: RuntimeScope): AbortSignal {\n this.controller ??= new AbortController();\n if (!this.live && !this.controller.signal.aborted) this.controller.abort();\n return this.controller.signal;\n}\n\nfunction onActivate(this: RuntimeScope, fn: () => void | Cleanup): void {\n ensureSetup(this);\n this.activations.push(fn);\n}\n\nfunction activateCallbacks(this: RuntimeScope): void {\n for (const fn of this.activations) {\n try {\n const result = fn();\n if (isPromise(result)) throw new Error(\"ZR_ASYNC_CLEANUP: activation returned a promise\");\n if (typeof result === \"function\") registerCleanup(this, result);\n } catch (error) {\n this.report(\"ZR_ACTIVATION_ERROR\", \"activation\", String(error));\n this.dispose();\n throw error;\n }\n }\n for (const effect of this.effects) effect.start();\n}\n\nfunction ensureSetup(scope: RuntimeScope): void {\n if (!scope.live || scope.activated || currentScope !== scope)\n throw new Error(\"ZR_SCOPE_SETUP: registration requires active setup\");\n}\nfunction onCleanup(this: RuntimeScope, fn: Cleanup): void {\n ensureSetup(this);\n registerCleanup(this, fn);\n}\nfunction registerCleanup(scope: RuntimeScope, fn: Cleanup): void {\n scope.cleanups.push(() => {\n if (isPromise(fn())) scope.report(\"ZR_ASYNC_CLEANUP\", \"cleanup\", \"cleanup returned a promise\");\n });\n}\n"]}
@@ -1,4 +1,3 @@
1
- /** The literal style surface shared by JSX typing and both renderers. */
2
1
  export declare const cssProperties: readonly ["accent-color", "align-content", "align-items", "align-self", "alignment-baseline", "all", "animation", "animation-composition", "animation-delay", "animation-direction", "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name", "animation-play-state", "animation-timing-function", "appearance", "aspect-ratio", "backdrop-filter", "backface-visibility", "background", "background-attachment", "background-blend-mode", "background-clip", "background-color", "background-image", "background-origin", "background-position", "background-position-x", "background-position-y", "background-repeat", "background-size", "block-size", "border", "border-block", "border-block-color", "border-block-end", "border-block-end-color", "border-block-end-style", "border-block-end-width", "border-block-start", "border-block-start-color", "border-block-start-style", "border-block-start-width", "border-block-style", "border-block-width", "border-bottom", "border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius", "border-bottom-style", "border-bottom-width", "border-collapse", "border-color", "border-end-end-radius", "border-end-start-radius", "border-image", "border-image-outset", "border-image-repeat", "border-image-slice", "border-image-source", "border-image-width", "border-inline", "border-inline-color", "border-inline-end", "border-inline-end-color", "border-inline-end-style", "border-inline-end-width", "border-inline-start", "border-inline-start-color", "border-inline-start-style", "border-inline-start-width", "border-inline-style", "border-inline-width", "border-left", "border-left-color", "border-left-style", "border-left-width", "border-radius", "border-right", "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-start-end-radius", "border-start-start-radius", "border-style", "border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style", "border-top-width", "border-width", "bottom", "box-align", "box-decoration-break", "box-flex", "box-ordinal-group", "box-orient", "box-pack", "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", "caption-side", "caret-color", "clear", "clip", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-scheme", "column-count", "column-fill", "column-gap", "column-rule", "column-rule-color", "column-rule-style", "column-rule-width", "column-span", "column-width", "columns", "contain", "contain-intrinsic-block-size", "contain-intrinsic-height", "contain-intrinsic-inline-size", "contain-intrinsic-size", "contain-intrinsic-width", "container", "container-name", "container-type", "content", "content-visibility", "counter-increment", "counter-reset", "counter-set", "cursor", "cx", "cy", "d", "direction", "display", "dominant-baseline", "empty-cells", "fill", "fill-opacity", "fill-rule", "filter", "flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", "float", "flood-color", "flood-opacity", "font", "font-family", "font-feature-settings", "font-kerning", "font-optical-sizing", "font-palette", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-synthesis", "font-synthesis-small-caps", "font-synthesis-style", "font-synthesis-weight", "font-variant", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-variation-settings", "font-weight", "forced-color-adjust", "gap", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns", "grid-template-rows", "height", "hyphenate-character", "hyphenate-limit-chars", "hyphens", "image-orientation", "image-rendering", "inline-size", "inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline", "inset-inline-end", "inset-inline-start", "isolation", "justify-content", "justify-items", "justify-self", "left", "letter-spacing", "lighting-color", "line-break", "line-clamp", "line-height", "list-style", "list-style-image", "list-style-position", "list-style-type", "margin", "margin-block", "margin-block-end", "margin-block-start", "margin-bottom", "margin-inline", "margin-inline-end", "margin-inline-start", "margin-left", "margin-right", "margin-top", "marker", "marker-end", "marker-mid", "marker-start", "mask", "mask-border", "mask-border-outset", "mask-border-repeat", "mask-border-slice", "mask-border-source", "mask-border-width", "mask-clip", "mask-composite", "mask-image", "mask-mode", "mask-origin", "mask-position", "mask-repeat", "mask-size", "mask-type", "math-depth", "math-style", "max-block-size", "max-height", "max-inline-size", "max-width", "min-block-size", "min-height", "min-inline-size", "min-width", "mix-blend-mode", "object-fit", "object-position", "offset", "offset-anchor", "offset-distance", "offset-path", "offset-position", "offset-rotate", "opacity", "order", "orphans", "outline", "outline-color", "outline-offset", "outline-style", "outline-width", "overflow", "overflow-anchor", "overflow-block", "overflow-clip-margin", "overflow-inline", "overflow-wrap", "overflow-x", "overflow-y", "overscroll-behavior", "overscroll-behavior-block", "overscroll-behavior-inline", "overscroll-behavior-x", "overscroll-behavior-y", "padding", "padding-block", "padding-block-end", "padding-block-start", "padding-bottom", "padding-inline", "padding-inline-end", "padding-inline-start", "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before", "page-break-inside", "paint-order", "perspective", "perspective-origin", "place-content", "place-items", "place-self", "pointer-events", "position", "print-color-adjust", "quotes", "r", "resize", "right", "rotate", "row-gap", "ruby-align", "ruby-position", "rx", "ry", "scale", "scroll-behavior", "scroll-margin", "scroll-margin-block", "scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom", "scroll-margin-inline", "scroll-margin-inline-end", "scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right", "scroll-margin-top", "scroll-padding", "scroll-padding-block", "scroll-padding-block-end", "scroll-padding-block-start", "scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end", "scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right", "scroll-padding-top", "scroll-snap-align", "scroll-snap-stop", "scroll-snap-type", "scrollbar-color", "scrollbar-gutter", "scrollbar-width", "shape-image-threshold", "shape-margin", "shape-outside", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "tab-size", "table-layout", "text-align", "text-align-last", "text-anchor", "text-box", "text-box-edge", "text-box-trim", "text-combine-upright", "text-decoration", "text-decoration-color", "text-decoration-line", "text-decoration-skip-ink", "text-decoration-style", "text-decoration-thickness", "text-emphasis", "text-emphasis-color", "text-emphasis-position", "text-emphasis-style", "text-indent", "text-orientation", "text-overflow", "text-rendering", "text-shadow", "text-size-adjust", "text-transform", "text-underline-offset", "text-underline-position", "text-wrap", "text-wrap-mode", "text-wrap-style", "top", "touch-action", "transform", "transform-box", "transform-origin", "transform-style", "transition", "transition-behavior", "transition-delay", "transition-duration", "transition-property", "transition-timing-function", "translate", "unicode-bidi", "user-select", "vector-effect", "vertical-align", "view-transition-class", "view-transition-name", "visibility", "white-space", "white-space-collapse", "widows", "width", "will-change", "word-break", "word-spacing", "writing-mode", "x", "y", "z-index", "zoom"];
3
2
  export declare const vendorProperties: readonly ["-webkit-appearance", "-webkit-backdrop-filter", "-webkit-line-clamp", "-webkit-mask", "-webkit-mask-image", "-webkit-mask-position", "-webkit-mask-size", "-webkit-text-fill-color", "-webkit-text-stroke", "-webkit-transform", "-webkit-user-select", "-moz-appearance", "-moz-osx-font-smoothing", "-moz-user-select", "-ms-overflow-style", "-ms-transform", "-ms-user-select"];
4
3
  export declare const unitlessProperties: readonly ["animation-iteration-count", "aspect-ratio", "column-count", "fill-opacity", "flex", "flex-grow", "flex-shrink", "flood-opacity", "font-weight", "grid-column", "grid-column-end", "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", "line-clamp", "line-height", "opacity", "order", "orphans", "scale", "stop-opacity", "stroke-miterlimit", "stroke-opacity", "tab-size", "widows", "z-index", "zoom"];