@absolutejs/absolute 0.19.0-beta.850 → 0.19.0-beta.852

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.
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
- // .angular-partial-tmp-ZJL7JH/src/core/streamingSlotRegistrar.ts
4
+ // .angular-partial-tmp-FGqhVS/src/core/streamingSlotRegistrar.ts
5
5
  var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
6
6
  var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
7
7
  var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
- // .angular-partial-tmp-ZJL7JH/src/core/streamingSlotRegistrar.ts
4
+ // .angular-partial-tmp-FGqhVS/src/core/streamingSlotRegistrar.ts
5
5
  var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
6
6
  var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
7
7
  var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
48
48
  getWarningController()?.maybeWarn(primitiveName);
49
49
  };
50
50
 
51
- // .angular-partial-tmp-ZJL7JH/src/core/streamingSlotRegistry.ts
51
+ // .angular-partial-tmp-FGqhVS/src/core/streamingSlotRegistry.ts
52
52
  var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
53
53
  var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
54
54
  var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
@@ -67,15 +67,6 @@ type HMRMessage = {
67
67
 
68
68
  type AngularHmrApi = {
69
69
  applyUpdate: (id: string, newCtor: unknown) => boolean;
70
- applyStyleUpdate?: (id: string, newCtor: unknown) => boolean;
71
- applyTemplateUpdate?: (id: string, newCtor: unknown) => boolean;
72
- applyServiceUpdate?: (id: string, newCtor: unknown) => boolean;
73
- beginStyleUpdateBatch?: () => void;
74
- endStyleUpdateBatch?: () => Array<{ id: string; ok: boolean }>;
75
- beginTemplateUpdateBatch?: () => void;
76
- endTemplateUpdateBatch?: () => Array<{ id: string; ok: boolean }>;
77
- beginServiceUpdateBatch?: () => void;
78
- endServiceUpdateBatch?: () => Array<{ id: string; ok: boolean }>;
79
70
  getRegistry?: () => Map<string, unknown>;
80
71
  refresh: () => void;
81
72
  hasPageExportsChanged?: (sourceId: string) => boolean;
@@ -348,223 +339,29 @@ const handleFastUpdate = async (message: HMRMessage) => {
348
339
  let activeMessage: Promise<void> | null = null;
349
340
  let pendingMessage: HMRMessage | null = null;
350
341
 
351
- /* Stub handlers for fast paths that aren't implemented yet. Each one
352
- * returns false to signal "couldn't handle, fall through to reboot",
353
- * letting Phase 2 ship piecewise — we land §2.1 (this dispatch table)
354
- * first, then §2.4 / §2.3 / §2.2 fill in the stubs one at a time
355
- * without further plumbing changes. */
356
- /* Template HMR — re-imports the rebuilt page chunk under FAST_PATCH +
357
- * TEMPLATE_UPDATE_MODE, then asks the runtime to swap the template
358
- * subgraph of `ɵcmp` (template factory, slot counts, queries,
359
- * dependencies, host bindings) on every re-registered component.
342
+ /* Surgical fast-path stubs.
360
343
  *
361
- * Live instances keep their state, services, queries, and DI tokens —
362
- * only the rendered output changes. After all components are patched,
363
- * a single `refresh()` call walks the subtree, marks each patched
364
- * component dirty, and ticks the app to repaint.
344
+ * Phase 2's dynamic-import-based handlers (component-style /
345
+ * template / service-method-only) are intentionally absent here
346
+ * they were architecturally wrong (dynamic-importing the rebuilt
347
+ * page chunk created a parallel class identity, tripping NG0912
348
+ * collisions and producing scope-ID drift on Emulated styles). The
349
+ * surgical pipeline that replaces them uses Angular'''s
350
+ * `ɵɵreplaceMetadata` primitive — see SURGICAL_HMR.md.
365
351
  *
366
- * Returns false on any partial failure so the orchestrator falls
367
- * through to a coherent reboot. */
368
- type TemplateUpdateWindow = FastPatchWindow & {
369
- __ANGULAR_HMR_TEMPLATE_UPDATE_MODE__?: boolean;
370
- };
371
-
372
- const handleTemplateUpdate = async (message: HMRMessage): Promise<boolean> => {
373
- const hmr = window.__ANGULAR_HMR__;
374
- if (
375
- !hmr ||
376
- !hmr.applyTemplateUpdate ||
377
- !hmr.beginTemplateUpdateBatch ||
378
- !hmr.endTemplateUpdateBatch
379
- ) {
380
- return false;
381
- }
382
-
383
- const indexPath = findIndexPath(
384
- message.data.manifest,
385
- message.data.sourceFile,
386
- 'angular'
387
- );
388
- if (!indexPath) return false;
389
-
390
- const w = window as TemplateUpdateWindow;
391
- w.__ANGULAR_HMR_FAST_PATCH__ = true;
392
- w.__ANGULAR_HMR_TEMPLATE_UPDATE_MODE__ = true;
393
- hmr.beginTemplateUpdateBatch();
394
-
395
- const origWarn = suppressNg0912();
396
- try {
397
- await import(`${indexPath}?t=${Date.now()}`);
398
-
399
- // Page-level routes/providers cannot ride a template update.
400
- if (hmr.hasPageExportsChanged?.(message.data.sourceFile || '')) {
401
- return false;
402
- }
403
-
404
- const results = hmr.endTemplateUpdateBatch();
405
- if (results.length === 0) return false;
406
- if (!results.every((r) => r.ok)) return false;
407
-
408
- console.warn = origWarn;
409
- hmr.refresh();
410
-
411
- return true;
412
- } catch (err) {
413
- console.warn = origWarn;
414
- console.warn(
415
- '[HMR] Angular template update failed, falling back:',
416
- err
417
- );
418
- return false;
419
- } finally {
420
- delete w.__ANGULAR_HMR_FAST_PATCH__;
421
- delete w.__ANGULAR_HMR_TEMPLATE_UPDATE_MODE__;
422
- console.warn = origWarn;
423
- }
424
- };
425
-
426
- /* Component-style HMR — re-imports the rebuilt page chunk under the
427
- * combined `FAST_PATCH` and `STYLE_UPDATE_MODE` flags so:
428
- * - the chunk's bootstrap section is skipped (FAST_PATCH)
429
- * - every per-file auto-registration block routes its new ctor
430
- * through `applyStyleUpdate` instead of a no-op (STYLE_UPDATE_MODE)
431
- *
432
- * The registration-block path is the only way to reach CHILD
433
- * components — the page chunk's `export *` only re-exports the page's
434
- * own module, so a top-level export walk would miss imported
435
- * components like `LayoutComponent`. Each compiled .ts file emits a
436
- * registration block for its own component classes, so the chunk
437
- * covers the whole tree on re-evaluation.
438
- *
439
- * Returns true iff every component the chunk re-registered swapped
440
- * its styles cleanly. Any failure (Shadow DOM, length change, missing
441
- * live <style> tag) → reboot. The transactional check inside
442
- * `applyStyleUpdate` means we never apply a partial update — either
443
- * the page restyles coherently or we reboot. */
444
- type StyleUpdateWindow = FastPatchWindow & {
445
- __ANGULAR_HMR_STYLE_UPDATE_MODE__?: boolean;
446
- };
352
+ * Until that pipeline lands, classifications other than
353
+ * `class-component` fall through to the existing reboot path. The
354
+ * toast tells the developer why. */
355
+ const handleTemplateUpdate = async (_message: HMRMessage): Promise<boolean> =>
356
+ false;
447
357
 
448
358
  const handleComponentStyleUpdate = async (
449
- message: HMRMessage
450
- ): Promise<boolean> => {
451
- const hmr = window.__ANGULAR_HMR__;
452
- if (
453
- !hmr ||
454
- !hmr.applyStyleUpdate ||
455
- !hmr.beginStyleUpdateBatch ||
456
- !hmr.endStyleUpdateBatch
457
- ) {
458
- return false;
459
- }
460
-
461
- const indexPath = findIndexPath(
462
- message.data.manifest,
463
- message.data.sourceFile,
464
- 'angular'
465
- );
466
- if (!indexPath) return false;
467
-
468
- const w = window as StyleUpdateWindow;
469
- w.__ANGULAR_HMR_FAST_PATCH__ = true;
470
- w.__ANGULAR_HMR_STYLE_UPDATE_MODE__ = true;
471
- hmr.beginStyleUpdateBatch();
472
-
473
- try {
474
- await import(`${indexPath}?t=${Date.now()}`);
475
-
476
- // Page-level routes/providers cannot ride a style update — they
477
- // are read once during bootstrap. If they changed in this
478
- // rebuild, reboot rather than risk a stale router/injector.
479
- if (hmr.hasPageExportsChanged?.(message.data.sourceFile || '')) {
480
- return false;
481
- }
482
-
483
- const results = hmr.endStyleUpdateBatch();
484
- if (results.length === 0) {
485
- // Chunk re-evaluated but no component re-registered — likely
486
- // the edited file isn't actually used by this page, or the
487
- // chunk skipped its registration block. Fall back to reboot.
488
- return false;
489
- }
490
- return results.every((r) => r.ok);
491
- } catch (err) {
492
- console.warn('[HMR] Angular style update failed, falling back:', err);
493
- return false;
494
- } finally {
495
- delete w.__ANGULAR_HMR_FAST_PATCH__;
496
- delete w.__ANGULAR_HMR_STYLE_UPDATE_MODE__;
497
- }
498
- };
499
-
500
- /* Service HMR — re-imports the rebuilt page chunk under FAST_PATCH +
501
- * SERVICE_UPDATE_MODE so the page's auto-registration block routes
502
- * each new service ctor through `applyServiceUpdate`. The runtime
503
- * does prototype method-swap (always) and best-effort field merge on
504
- * the live singleton (when reachable via the root injector and
505
- * donor-instantiable). Live components keep their references — they
506
- * just call into the new method bodies on next invocation.
507
- *
508
- * This path only runs when the server-side classifier returned
509
- * `service-method-only` — services with side-effecting constructors
510
- * never get here, so the live singleton's existing subscriptions /
511
- * timers / listeners stay intact and we don't double-register them. */
512
- type ServiceUpdateWindow = FastPatchWindow & {
513
- __ANGULAR_HMR_SERVICE_UPDATE_MODE__?: boolean;
514
- };
359
+ _message: HMRMessage
360
+ ): Promise<boolean> => false;
515
361
 
516
362
  const handleServiceMethodSwap = async (
517
- message: HMRMessage
518
- ): Promise<boolean> => {
519
- const hmr = window.__ANGULAR_HMR__;
520
- if (
521
- !hmr ||
522
- !hmr.applyServiceUpdate ||
523
- !hmr.beginServiceUpdateBatch ||
524
- !hmr.endServiceUpdateBatch
525
- ) {
526
- return false;
527
- }
528
-
529
- const indexPath = findIndexPath(
530
- message.data.manifest,
531
- message.data.sourceFile,
532
- 'angular'
533
- );
534
- if (!indexPath) return false;
535
-
536
- const w = window as ServiceUpdateWindow;
537
- w.__ANGULAR_HMR_FAST_PATCH__ = true;
538
- w.__ANGULAR_HMR_SERVICE_UPDATE_MODE__ = true;
539
- hmr.beginServiceUpdateBatch();
540
-
541
- try {
542
- await import(`${indexPath}?t=${Date.now()}`);
543
-
544
- // Page-level routes/providers cannot ride a service update.
545
- if (hmr.hasPageExportsChanged?.(message.data.sourceFile || '')) {
546
- return false;
547
- }
548
-
549
- const results = hmr.endServiceUpdateBatch();
550
- if (results.length === 0) return false;
551
- if (!results.every((r) => r.ok)) return false;
552
-
553
- // New method bodies might compute new values for observable-fed
554
- // fields, so the existing component subtree should re-render.
555
- // `refresh()` ticks the app + marks any pending fast-patch
556
- // components dirty.
557
- hmr.refresh();
558
-
559
- return true;
560
- } catch (err) {
561
- console.warn('[HMR] Angular service update failed, falling back:', err);
562
- return false;
563
- } finally {
564
- delete w.__ANGULAR_HMR_FAST_PATCH__;
565
- delete w.__ANGULAR_HMR_SERVICE_UPDATE_MODE__;
566
- }
567
- };
363
+ _message: HMRMessage
364
+ ): Promise<boolean> => false;
568
365
 
569
366
  const logRebootReason = (message: HMRMessage) => {
570
367
  const reason = message.data.reason;
@@ -26,21 +26,6 @@ type AngularComponentDefinition = {
26
26
  providers?: unknown;
27
27
  providersResolver?: unknown;
28
28
  selectors?: unknown[];
29
- styles?: string[];
30
- encapsulation?: number;
31
- template?: unknown;
32
- consts?: unknown;
33
- decls?: number;
34
- vars?: number;
35
- viewQuery?: unknown;
36
- contentQueries?: unknown;
37
- ngContentSelectors?: unknown;
38
- dependencies?: unknown;
39
- hostBindings?: unknown;
40
- hostVars?: number;
41
- hostAttrs?: unknown;
42
- inputs?: unknown;
43
- outputs?: unknown;
44
29
  };
45
30
 
46
31
  type ComponentCtor = (abstract new (...args: never[]) => unknown) & {
@@ -160,45 +145,6 @@ const hasProviderChanges = (oldCtor: ComponentCtor, newCtor: ComponentCtor) => {
160
145
  return false;
161
146
  };
162
147
 
163
- /* Style-update batch buffer.
164
- *
165
- * When a component-CSS edit triggers HMR, the rebuilt page chunk
166
- * re-evaluates with `__ANGULAR_HMR_STYLE_UPDATE_MODE__` set on the
167
- * window. Inside that mode, every `register(id, newCtor)` call from
168
- * the chunk's auto-registration block routes its newCtor straight
169
- * into `applyStyleUpdate(id, newCtor)` instead of being a no-op
170
- * (which is the default for already-registered IDs).
171
- *
172
- * This is the only way to reach CHILD-component classes — the page
173
- * chunk only `export *`s the page's own module, so a top-level
174
- * `Object.keys(newModule)` walk wouldn't find imported components.
175
- * The registration block runs once per compiled file (page + every
176
- * imported component), so it covers the whole subtree.
177
- *
178
- * The batch is consulted by `handleComponentStyleUpdate` after the
179
- * chunk import resolves: if any registration's update returned false,
180
- * the orchestrator falls through to a full reboot rather than leaving
181
- * the page partially restyled. */
182
-
183
- type StyleUpdateMode = typeof globalThis & {
184
- __ANGULAR_HMR_STYLE_UPDATE_MODE__?: boolean;
185
- };
186
-
187
- type StyleBatchEntry = { id: string; ok: boolean };
188
-
189
- const styleUpdateBatch: StyleBatchEntry[] = [];
190
-
191
- const beginStyleUpdateBatch = () => {
192
- styleUpdateBatch.length = 0;
193
- };
194
-
195
- const endStyleUpdateBatch = (): StyleBatchEntry[] => {
196
- const out = styleUpdateBatch.slice();
197
- styleUpdateBatch.length = 0;
198
-
199
- return out;
200
- };
201
-
202
148
  const register = (id: string, ctor: unknown) => {
203
149
  if (!id || !isComponentCtor(ctor)) return;
204
150
  if (!componentRegistry.has(id)) {
@@ -208,34 +154,6 @@ const register = (id: string, ctor: unknown) => {
208
154
  registeredAt: Date.now(),
209
155
  updateCount: 0
210
156
  });
211
-
212
- return;
213
- }
214
-
215
- // Already registered. If we're inside an HMR style-update or
216
- // template-update window, route this re-registration's new ctor
217
- // through the appropriate surgical patcher. The per-file
218
- // auto-registration block is the only place to intercept new ctors
219
- // for CHILD components — the page chunk's `export *` only re-exports
220
- // the page's own module.
221
- const styleScope = globalThis as StyleUpdateMode;
222
- if (styleScope.__ANGULAR_HMR_STYLE_UPDATE_MODE__) {
223
- const ok = applyStyleUpdate(id, ctor);
224
- styleUpdateBatch.push({ id, ok });
225
-
226
- return;
227
- }
228
- const tmplScope = globalThis as TemplateUpdateMode;
229
- if (tmplScope.__ANGULAR_HMR_TEMPLATE_UPDATE_MODE__) {
230
- const ok = applyTemplateUpdate(id, ctor);
231
- templateUpdateBatch.push({ id, ok });
232
-
233
- return;
234
- }
235
- const svcScope = globalThis as ServiceUpdateMode;
236
- if (svcScope.__ANGULAR_HMR_SERVICE_UPDATE_MODE__) {
237
- const ok = applyServiceUpdate(id, ctor);
238
- serviceUpdateBatch.push({ id, ok });
239
157
  }
240
158
  };
241
159
 
@@ -349,383 +267,6 @@ const markPatchedDirty = (ctor: ComponentCtor) => {
349
267
  }
350
268
  };
351
269
 
352
- /* Component-style HMR — swaps `ɵcmp.styles` and replaces matching
353
- * `<style>` tags in the document so the visible page reflects the new
354
- * CSS without a re-bootstrap.
355
- *
356
- * Why this is safe with Emulated encapsulation (the default): Angular's
357
- * compiler rewrites the CSS at build time, prefixing every selector
358
- * with `[_ngcontent-c<scopeId>]`. The scope ID is deterministic per
359
- * component def — the same source file produces the same scope ID
360
- * across rebuilds — so the rewritten DOM still matches the new CSS.
361
- * We only need to update the style *content*; the elements wearing
362
- * `_ngcontent-c<scopeId>` attributes are still on the page from the
363
- * initial bootstrap.
364
- *
365
- * ShadowDOM encapsulation (3) is not yet handled — each component
366
- * instance has its own shadow root with its own style tags, requiring
367
- * a per-instance walk. Falls through to reboot for now.
368
- *
369
- * The matching strategy: walk every `<style>` tag in `document.head`
370
- * and `document.body`, find ones whose `textContent` exactly matches a
371
- * string in the OLD `ɵcmp.styles` array, and replace it with the
372
- * corresponding string from the NEW array. Equal-length arrays only —
373
- * adding or removing a `styleUrl` entry triggers a reboot.
374
- *
375
- * Returns true on full success, false if we couldn't safely apply
376
- * (length mismatch, ShadowDOM, missing styles array, or any old
377
- * style had no DOM match — meaning we'd leave the page in a partially
378
- * updated state). */
379
-
380
- const SHADOW_DOM_ENCAPSULATION = 3;
381
-
382
- type StyleHost = {
383
- host: ParentNode;
384
- tags: HTMLStyleElement[];
385
- };
386
-
387
- const collectStyleHosts = (): StyleHost[] => {
388
- const hosts: StyleHost[] = [];
389
- const headTags = Array.from(
390
- document.head.querySelectorAll('style')
391
- ) as HTMLStyleElement[];
392
- const bodyTags = Array.from(
393
- document.body.querySelectorAll('style')
394
- ) as HTMLStyleElement[];
395
- if (headTags.length > 0)
396
- hosts.push({ host: document.head, tags: headTags });
397
- if (bodyTags.length > 0)
398
- hosts.push({ host: document.body, tags: bodyTags });
399
-
400
- return hosts;
401
- };
402
-
403
- const findStyleTagByContent = (
404
- hosts: StyleHost[],
405
- content: string,
406
- consumed: Set<HTMLStyleElement>
407
- ): HTMLStyleElement | null => {
408
- for (const { tags } of hosts) {
409
- for (const tag of tags) {
410
- if (consumed.has(tag)) continue;
411
- if (tag.textContent === content) return tag;
412
- }
413
- }
414
-
415
- return null;
416
- };
417
-
418
- const applyStyleUpdate = (id: string, newCtor: unknown) => {
419
- if (!isComponentCtor(newCtor)) return false;
420
-
421
- const entry = componentRegistry.get(id);
422
- if (!entry) {
423
- // First time we've seen this component — register it but no styles
424
- // to swap yet. The next edit will pick up the now-registered ctor.
425
- register(id, newCtor);
426
-
427
- return true;
428
- }
429
-
430
- const { liveCtor } = entry;
431
- if (liveCtor === newCtor) return true;
432
-
433
- const liveCmp = liveCtor.ɵcmp;
434
- const newCmp = newCtor.ɵcmp;
435
- if (!liveCmp || !newCmp) return false;
436
-
437
- if (
438
- liveCmp.encapsulation === SHADOW_DOM_ENCAPSULATION ||
439
- newCmp.encapsulation === SHADOW_DOM_ENCAPSULATION
440
- ) {
441
- // Shadow DOM scopes styles per-instance — out of scope for v1.
442
- return false;
443
- }
444
-
445
- const oldStyles = liveCmp.styles;
446
- const nextStyles = newCmp.styles;
447
- if (!Array.isArray(oldStyles) || !Array.isArray(nextStyles)) return false;
448
- if (oldStyles.length !== nextStyles.length) return false;
449
- if (oldStyles.length === 0) {
450
- // No styles to swap, no work to do — succeed trivially.
451
- liveCmp.styles = nextStyles;
452
-
453
- return true;
454
- }
455
-
456
- const hosts = collectStyleHosts();
457
- const consumed = new Set<HTMLStyleElement>();
458
- const matches: { tag: HTMLStyleElement; nextContent: string }[] = [];
459
-
460
- for (let i = 0; i < oldStyles.length; i++) {
461
- const oldContent = oldStyles[i] ?? '';
462
- const nextContent = nextStyles[i] ?? '';
463
- if (oldContent === nextContent) continue;
464
- const tag = findStyleTagByContent(hosts, oldContent, consumed);
465
- if (!tag) {
466
- // Couldn't locate one of the live <style> tags — fall through
467
- // to reboot rather than leaving the page in a half-updated
468
- // state.
469
- return false;
470
- }
471
- consumed.add(tag);
472
- matches.push({ tag, nextContent });
473
- }
474
-
475
- // Only mutate after we've verified we can update every diffed style.
476
- for (const { tag, nextContent } of matches) {
477
- tag.textContent = nextContent;
478
- }
479
- liveCmp.styles = nextStyles;
480
-
481
- updateCounter.value++;
482
- entry.updateCount++;
483
- entry.registeredAt = Date.now();
484
-
485
- return true;
486
- };
487
-
488
- /* Template HMR — surgical swap of the template-related fields on a
489
- * registered component's `ɵcmp` so the live instance re-renders with
490
- * the new template WITHOUT re-instantiating. Inputs, outputs, host
491
- * bindings, providers, and lifecycle hooks live on the class
492
- * prototype + ɵcmp, and we leave those alone — only the template
493
- * factory and the slot counts/queries that depend on it are replaced.
494
- *
495
- * Why a defined list of fields and not a full `ɵcmp` swap: a wholesale
496
- * `Object.assign(liveCmp, newCmp)` would also overwrite `providers /
497
- * providersResolver` and other class-level metadata. Those changes
498
- * already require a full reboot (the existing fast-path handler in
499
- * `angular.ts` checks `hasProviderChanges` and bails). For a pure
500
- * template edit, restricting the patch to the template subgraph
501
- * keeps live instances on the same DI tokens, queryList references,
502
- * input bindings, etc. — only the rendered output changes.
503
- *
504
- * After the swap, the component's TView (the cached view layout) is
505
- * stale because slot counts may have changed. Angular regenerates the
506
- * TView lazily on the first re-render, but only if the existing one
507
- * is invalidated — which happens automatically when we walk the live
508
- * instances and call `applyChanges`. The same `markPatchedDirty`
509
- * helper used by `applyUpdate` covers OnPush views too. */
510
-
511
- const TEMPLATE_PATCH_FIELDS = [
512
- 'template',
513
- 'consts',
514
- 'decls',
515
- 'vars',
516
- 'viewQuery',
517
- 'contentQueries',
518
- 'ngContentSelectors',
519
- 'dependencies',
520
- 'hostBindings',
521
- 'hostVars',
522
- 'hostAttrs',
523
- 'inputs',
524
- 'outputs'
525
- ] as const;
526
-
527
- const applyTemplateUpdate = (id: string, newCtor: unknown) => {
528
- if (!isComponentCtor(newCtor)) return false;
529
-
530
- const entry = componentRegistry.get(id);
531
- if (!entry) {
532
- register(id, newCtor);
533
-
534
- return true;
535
- }
536
-
537
- const { liveCtor } = entry;
538
- if (liveCtor === newCtor) return true;
539
-
540
- const liveCmp = liveCtor.ɵcmp as Record<string, unknown> | undefined;
541
- const nextCmp = newCtor.ɵcmp as Record<string, unknown> | undefined;
542
- if (!liveCmp || !nextCmp) return false;
543
-
544
- // If providers changed, this isn't a pure template edit anymore —
545
- // fall back to reboot via the caller.
546
- if (hasProviderChanges(liveCtor, newCtor)) return false;
547
-
548
- for (const field of TEMPLATE_PATCH_FIELDS) {
549
- if (Object.prototype.hasOwnProperty.call(nextCmp, field)) {
550
- liveCmp[field] = nextCmp[field];
551
- }
552
- }
553
-
554
- pendingFastPatchRefresh.add(liveCtor);
555
- updateCounter.value++;
556
- entry.updateCount++;
557
- entry.registeredAt = Date.now();
558
-
559
- return true;
560
- };
561
-
562
- type TemplateUpdateMode = typeof globalThis & {
563
- __ANGULAR_HMR_TEMPLATE_UPDATE_MODE__?: boolean;
564
- };
565
-
566
- const templateUpdateBatch: StyleBatchEntry[] = [];
567
-
568
- const beginTemplateUpdateBatch = () => {
569
- templateUpdateBatch.length = 0;
570
- };
571
-
572
- const endTemplateUpdateBatch = (): StyleBatchEntry[] => {
573
- const out = templateUpdateBatch.slice();
574
- templateUpdateBatch.length = 0;
575
-
576
- return out;
577
- };
578
-
579
- /* Service HMR — Level 3 hybrid:
580
- * 1. Always swap prototype methods on the live ctor. Reaches every
581
- * live instance (singletons + transient injectees) because they
582
- * all share the same prototype.
583
- * 2. If the live singleton is reachable via the root injector,
584
- * attempt to instantiate a donor with the new ctor and copy any
585
- * OWN PROPERTIES that the live singleton is missing — this picks
586
- * up new class-field initializers without overwriting accumulated
587
- * runtime state. Donor instantiation is best-effort: services
588
- * using `inject()` outside of an injection context will throw,
589
- * and we just skip the field merge in that case (the prototype
590
- * swap still applies, so method changes take effect).
591
- * 3. The classifier only routes here for services with NO
592
- * side-effecting calls in the constructor / field initializers
593
- * (no `subscribe / setInterval / addEventListener / effect /
594
- * new Worker / new EventSource / etc.`). Anything that touches
595
- * external state at construction time falls through to reboot
596
- * via the server-side classification, never reaching this code
597
- * path. */
598
-
599
- type AppRefWithInjector = {
600
- injector?: { get?: (token: unknown, notFoundValue?: unknown) => unknown };
601
- };
602
-
603
- const getRootInjector = (): {
604
- get: (token: unknown, notFoundValue?: unknown) => unknown;
605
- } | null => {
606
- const app = window.__ANGULAR_APP__ as AppRefWithInjector | null;
607
- if (!app || !app.injector || typeof app.injector.get !== 'function') {
608
- return null;
609
- }
610
-
611
- return app.injector as {
612
- get: (token: unknown, notFoundValue?: unknown) => unknown;
613
- };
614
- };
615
-
616
- const swapPrototypeMethods = (
617
- liveCtor: ComponentCtor,
618
- newCtor: ComponentCtor
619
- ) => {
620
- const newProto = newCtor.prototype as Record<string, unknown>;
621
- const liveProto = liveCtor.prototype as Record<string, unknown>;
622
- Object.getOwnPropertyNames(newProto).forEach((prop) => {
623
- if (prop === 'constructor') return;
624
- try {
625
- const desc = Object.getOwnPropertyDescriptor(newProto, prop);
626
- if (desc) Object.defineProperty(liveProto, prop, desc);
627
- } catch {
628
- /* non-configurable property — skip */
629
- }
630
- });
631
- };
632
-
633
- const tryInstantiateServiceDonor = (newCtor: ComponentCtor): unknown | null => {
634
- try {
635
- // `new newCtor()` with no args. Works for services with no
636
- // constructor params and no `inject()` calls at field-init time.
637
- // Anything more sophisticated (services that use `inject()`
638
- // outside an injection context) throws here and we fall back to
639
- // prototype-only swap.
640
- return Reflect.construct(newCtor as unknown as new () => unknown, []);
641
- } catch {
642
- return null;
643
- }
644
- };
645
-
646
- const mergeMissingFields = (
647
- liveInstance: Record<string, unknown>,
648
- donor: Record<string, unknown>
649
- ) => {
650
- let merged = 0;
651
- Object.getOwnPropertyNames(donor).forEach((prop) => {
652
- if (Object.prototype.hasOwnProperty.call(liveInstance, prop)) return;
653
- try {
654
- const desc = Object.getOwnPropertyDescriptor(donor, prop);
655
- if (desc) {
656
- Object.defineProperty(liveInstance, prop, desc);
657
- merged++;
658
- }
659
- } catch {
660
- /* defining the property failed — skip */
661
- }
662
- });
663
-
664
- return merged;
665
- };
666
-
667
- const applyServiceUpdate = (id: string, newCtor: unknown) => {
668
- if (!isComponentCtor(newCtor)) return false;
669
-
670
- const entry = componentRegistry.get(id);
671
- if (!entry) {
672
- register(id, newCtor);
673
-
674
- return true;
675
- }
676
-
677
- const { liveCtor } = entry;
678
- if (liveCtor === newCtor) return true;
679
-
680
- // Method swap — reaches every live instance.
681
- swapPrototypeMethods(liveCtor, newCtor);
682
-
683
- // Best-effort field merge on the live singleton.
684
- const injector = getRootInjector();
685
- if (injector) {
686
- try {
687
- const liveInstance = injector.get(liveCtor, null) as Record<
688
- string,
689
- unknown
690
- > | null;
691
- if (liveInstance) {
692
- const donor = tryInstantiateServiceDonor(newCtor) as Record<
693
- string,
694
- unknown
695
- > | null;
696
- if (donor) mergeMissingFields(liveInstance, donor);
697
- }
698
- } catch {
699
- /* injector lookup failed — service may not be `providedIn:
700
- "root"`, or the type-token mismatched. Prototype swap is
701
- already applied, so methods take effect either way. */
702
- }
703
- }
704
-
705
- updateCounter.value++;
706
- entry.updateCount++;
707
- entry.registeredAt = Date.now();
708
-
709
- return true;
710
- };
711
-
712
- type ServiceUpdateMode = typeof globalThis & {
713
- __ANGULAR_HMR_SERVICE_UPDATE_MODE__?: boolean;
714
- };
715
-
716
- const serviceUpdateBatch: StyleBatchEntry[] = [];
717
-
718
- const beginServiceUpdateBatch = () => {
719
- serviceUpdateBatch.length = 0;
720
- };
721
-
722
- const endServiceUpdateBatch = (): StyleBatchEntry[] => {
723
- const out = serviceUpdateBatch.slice();
724
- serviceUpdateBatch.length = 0;
725
-
726
- return out;
727
- };
728
-
729
270
  const applyUpdate = (id: string, newCtor: unknown) => {
730
271
  if (!isComponentCtor(newCtor)) return false;
731
272
 
@@ -861,16 +402,7 @@ const hasPageExportsChanged = (sourceId: string): boolean => {
861
402
  export const installAngularHMRRuntime = () => {
862
403
  if (typeof window === 'undefined') return;
863
404
  window.__ANGULAR_HMR__ = {
864
- applyServiceUpdate,
865
- applyStyleUpdate,
866
- applyTemplateUpdate,
867
405
  applyUpdate,
868
- beginServiceUpdateBatch,
869
- beginStyleUpdateBatch,
870
- beginTemplateUpdateBatch,
871
- endServiceUpdateBatch,
872
- endStyleUpdateBatch,
873
- endTemplateUpdateBatch,
874
406
  getStats: getAngularHmrStats,
875
407
  hasPageExportsChanged,
876
408
  recordPageExports,
@@ -8,7 +8,7 @@
8
8
  "import type { RuntimeIslandRenderProps } from '../../types/island';\nimport { getIslandMarkerAttributes } from '../core/islandMarkupAttributes';\n\ntype PreservedIslandMarkup = {\n\tattributes: Record<string, string>;\n\tinnerHTML: string;\n};\n\ntype IslandMarkerElement = HTMLElement & {\n\tdataset: DOMStringMap & {\n\t\tcomponent?: string;\n\t\tframework?: string;\n\t\thydrate?: string;\n\t\tisland?: string;\n\t\tislandId?: string;\n\t\tprops?: string;\n\t};\n};\n\nconst getClaimMap = () => {\n\tif (typeof window === 'undefined') {\n\t\treturn null;\n\t}\n\n\twindow.__ABS_CLAIMED_ISLAND_MARKUP__ ??= new Map<string, number>();\n\n\treturn window.__ABS_CLAIMED_ISLAND_MARKUP__;\n};\n\nconst getSnapshotMap = () => {\n\tif (typeof window === 'undefined') {\n\t\treturn null;\n\t}\n\n\twindow.__ABS_SERVER_ISLAND_HTML__ ??= new Map<\n\t\tstring,\n\t\tPreservedIslandMarkup[]\n\t>();\n\n\treturn window.__ABS_SERVER_ISLAND_HTML__;\n};\n\nconst getIslandSignature = (props: RuntimeIslandRenderProps) => {\n\tconst attributes = getIslandMarkerAttributes(props);\n\n\treturn [\n\t\tattributes['data-component'],\n\t\tattributes['data-framework'],\n\t\tattributes['data-hydrate'],\n\t\tattributes['data-props']\n\t].join('::');\n};\n\nconst isMatchingIslandElement = (\n\telement: Element,\n\tprops: RuntimeIslandRenderProps\n): element is IslandMarkerElement => {\n\tif (!(element instanceof HTMLElement)) {\n\t\treturn false;\n\t}\n\n\tconst attributes = getIslandMarkerAttributes(props);\n\n\treturn (\n\t\telement.dataset.island === 'true' &&\n\t\telement.dataset.component === attributes['data-component'] &&\n\t\telement.dataset.framework === attributes['data-framework'] &&\n\t\t(element.dataset.hydrate ?? 'load') === attributes['data-hydrate'] &&\n\t\t(element.dataset.props ?? '{}') === attributes['data-props']\n\t);\n};\n\nconst snapshotIslandElement = (\n\telement: HTMLElement,\n\tsnapshotMap: Map<string, PreservedIslandMarkup[]>\n) => {\n\tconst signature = [\n\t\telement.dataset.component,\n\t\telement.dataset.framework,\n\t\telement.dataset.hydrate ?? 'load',\n\t\telement.dataset.props ?? '{}'\n\t].join('::');\n\tconst existing = snapshotMap.get(signature) ?? [];\n\tconst attributes = Object.fromEntries(\n\t\telement\n\t\t\t.getAttributeNames()\n\t\t\t.map((name) => [name, element.getAttribute(name) ?? ''])\n\t);\n\texisting.push({\n\t\tattributes,\n\t\tinnerHTML: element.innerHTML\n\t});\n\tsnapshotMap.set(signature, existing);\n};\n\nexport const initializeIslandMarkupSnapshot = () => {\n\tif (typeof document === 'undefined') {\n\t\treturn;\n\t}\n\n\tconst snapshotMap = getSnapshotMap();\n\tif (!snapshotMap || snapshotMap.size > 0) {\n\t\treturn;\n\t}\n\n\tconst elements = Array.from(\n\t\tdocument.querySelectorAll<HTMLElement>('[data-island=\"true\"]')\n\t);\n\tfor (const element of elements) {\n\t\tsnapshotIslandElement(element, snapshotMap);\n\t}\n};\n\nexport const preserveIslandMarkup = (props: RuntimeIslandRenderProps) => {\n\tif (typeof document === 'undefined') {\n\t\treturn {\n\t\t\tattributes: getIslandMarkerAttributes(props),\n\t\t\tinnerHTML: ''\n\t\t};\n\t}\n\n\tconst claimMap = getClaimMap();\n\tconst snapshotMap = getSnapshotMap();\n\tconst signature = getIslandSignature(props);\n\tconst claimedCount = claimMap?.get(signature) ?? 0;\n\tconst snapshotCandidate = snapshotMap?.get(signature)?.[claimedCount];\n\tconst candidates = Array.from(\n\t\tdocument.querySelectorAll('[data-island=\"true\"]')\n\t).filter((element) => isMatchingIslandElement(element, props));\n\tconst candidate = candidates[claimedCount];\n\tif (claimMap) {\n\t\tclaimMap.set(signature, claimedCount + 1);\n\t}\n\n\treturn {\n\t\tattributes:\n\t\t\tsnapshotCandidate?.attributes ?? getIslandMarkerAttributes(props),\n\t\tinnerHTML: snapshotCandidate?.innerHTML ?? candidate?.innerHTML ?? ''\n\t};\n};\n",
9
9
  "import type { RuntimeIslandRenderProps } from '../../types/island';\nimport { preserveIslandMarkup } from '../client/preserveIslandMarkup';\n\nexport const Island = (props: RuntimeIslandRenderProps) => {\n\tconst { attributes, innerHTML } = preserveIslandMarkup(props);\n\n\treturn (\n\t\t<div\n\t\t\t{...attributes}\n\t\t\tdangerouslySetInnerHTML={{ __html: innerHTML }}\n\t\t\tsuppressHydrationWarning\n\t\t/>\n\t);\n};\n",
10
10
  "import type {\n\tIslandRegistry,\n\tIslandRegistryInput,\n\tTypedIslandRenderProps\n} from '../../types/island';\nimport { preserveIslandMarkup } from '../client/preserveIslandMarkup';\n\nexport const createTypedIsland = <T extends IslandRegistryInput>(\n\t_registry: IslandRegistry<T>\n) => {\n\tconst Island = (props: TypedIslandRenderProps<T>) => {\n\t\tconst { attributes, innerHTML } = preserveIslandMarkup(props);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\t{...attributes}\n\t\t\t\tdangerouslySetInnerHTML={{ __html: innerHTML }}\n\t\t\t\tsuppressHydrationWarning\n\t\t\t/>\n\t\t);\n\t};\n\n\treturn Island;\n};\n",
11
- "import { createElement, type ReactNode } from 'react';\n\nexport type UniversalRouterProps = {\n\t/** The request URL to seed `<StaticRouter>` with on the server. Pages\n\t * typically forward `props.url` (auto-injected by handleReactPageRequest\n\t * from `request.url`). Ignored in the browser, where `<BrowserRouter>`\n\t * reads `window.location` directly. Defaults to '/'. */\n\turl?: string;\n\tchildren?: ReactNode;\n};\n\n/** SSR-safe wrapper around react-router that picks `<StaticRouter>` on the\n * server and `<BrowserRouter>` in the browser. Without it, every SPA page\n * has to write its own `typeof window === 'undefined'` branch and import\n * both routers — boilerplate that's the same in every page.\n *\n * Usage:\n *\n * export const MySpa = ({ url }: { url?: string }) => (\n * <html>\n * <Head />\n * <body>\n * <UniversalRouter url={url}>\n * <Routes>\n * <Route path=\"/foo\" element={<Foo />} />\n * </Routes>\n * </UniversalRouter>\n * </body>\n * </html>\n * );\n *\n * Implementation note: `react-router` is required lazily via\n * `createRequire` so consumers who don't use `UniversalRouter` aren't\n * forced to install react-router just to import other things from\n * `@absolutejs/absolute/react` (the previous eager static import made\n * `dist/react/index.js` carry a `import \"react-router\"` that broke\n * every consumer's bundle who hadn't installed it). Bun resolves the\n * CJS interop synchronously, so render is still purely synchronous.\n *\n * `<BrowserRouter>` reads `window.history` at construction, so it\n * throws if instantiated on the server. The `typeof window` check has\n * to live at render time (not import time) because the module is\n * loaded in both environments. */\n\ntype ReactRouterModule = {\n\tBrowserRouter: (...args: unknown[]) => unknown;\n\tStaticRouter: (...args: unknown[]) => unknown;\n};\n\nlet cachedReactRouter: ReactRouterModule | null = null;\n\nconst loadReactRouter = (): ReactRouterModule => {\n\tif (cachedReactRouter) return cachedReactRouter;\n\n\t// Hide the bare specifier behind a Function-constructor so static\n\t// bundlers can't analyze it — they only see a `Function(string)`\n\t// call, not an `import \"react-router\"`. Resolution happens at\n\t// render time and only on the first call to `UniversalRouter`,\n\t// so consumers who never use it never pay the install cost.\n\t// `require` is available in Bun's CJS-interop context (server)\n\t// and in any bundle output that emitted a CJS-compatible runtime.\n\ttry {\n\t\tconst dynamicRequire = new Function('spec', 'return require(spec)') as (\n\t\t\tspec: string\n\t\t) => ReactRouterModule;\n\t\tcachedReactRouter = dynamicRequire('react-router');\n\n\t\treturn cachedReactRouter;\n\t} catch {\n\t\tconst fromWindow = (\n\t\t\tglobalThis as { ReactRouterDOM?: ReactRouterModule }\n\t\t).ReactRouterDOM;\n\t\tif (fromWindow) {\n\t\t\tcachedReactRouter = fromWindow;\n\n\t\t\treturn cachedReactRouter;\n\t\t}\n\t\tthrow new Error(\n\t\t\t'[UniversalRouter] react-router is not installed. Install it with `bun add react-router` to use UniversalRouter.'\n\t\t);\n\t}\n};\n\nexport const UniversalRouter = ({ url, children }: UniversalRouterProps) => {\n\tconst { BrowserRouter, StaticRouter } = loadReactRouter();\n\tif (typeof window === 'undefined') {\n\t\treturn createElement(StaticRouter, { location: url ?? '/' }, children);\n\t}\n\n\treturn createElement(BrowserRouter, null, children);\n};\n",
11
+ "import { createElement, type ComponentType, type ReactNode } from 'react';\n\nexport type UniversalRouterProps = {\n\t/** The request URL to seed `<StaticRouter>` with on the server. Pages\n\t * typically forward `props.url` (auto-injected by handleReactPageRequest\n\t * from `request.url`). Ignored in the browser, where `<BrowserRouter>`\n\t * reads `window.location` directly. Defaults to '/'. */\n\turl?: string;\n\tchildren?: ReactNode;\n};\n\n/** SSR-safe wrapper around react-router that picks `<StaticRouter>` on the\n * server and `<BrowserRouter>` in the browser. Without it, every SPA page\n * has to write its own `typeof window === 'undefined'` branch and import\n * both routers — boilerplate that's the same in every page.\n *\n * Usage:\n *\n * export const MySpa = ({ url }: { url?: string }) => (\n * <html>\n * <Head />\n * <body>\n * <UniversalRouter url={url}>\n * <Routes>\n * <Route path=\"/foo\" element={<Foo />} />\n * </Routes>\n * </UniversalRouter>\n * </body>\n * </html>\n * );\n *\n * Implementation note: `react-router` is required lazily via\n * `createRequire` so consumers who don't use `UniversalRouter` aren't\n * forced to install react-router just to import other things from\n * `@absolutejs/absolute/react` (the previous eager static import made\n * `dist/react/index.js` carry a `import \"react-router\"` that broke\n * every consumer's bundle who hadn't installed it). Bun resolves the\n * CJS interop synchronously, so render is still purely synchronous.\n *\n * `<BrowserRouter>` reads `window.history` at construction, so it\n * throws if instantiated on the server. The `typeof window` check has\n * to live at render time (not import time) because the module is\n * loaded in both environments. */\n\ntype ReactRouterModule = {\n\tBrowserRouter: ComponentType<{ children?: ReactNode }>;\n\tStaticRouter: ComponentType<{ location: string; children?: ReactNode }>;\n};\n\nlet cachedReactRouter: ReactRouterModule | null = null;\n\nconst loadReactRouter = (): ReactRouterModule => {\n\tif (cachedReactRouter) return cachedReactRouter;\n\n\t// Hide the bare specifier behind a Function-constructor so static\n\t// bundlers can't analyze it — they only see a `Function(string)`\n\t// call, not an `import \"react-router\"`. Resolution happens at\n\t// render time and only on the first call to `UniversalRouter`,\n\t// so consumers who never use it never pay the install cost.\n\t// `require` is available in Bun's CJS-interop context (server)\n\t// and in any bundle output that emitted a CJS-compatible runtime.\n\ttry {\n\t\tconst dynamicRequire = new Function('spec', 'return require(spec)') as (\n\t\t\tspec: string\n\t\t) => ReactRouterModule;\n\t\tcachedReactRouter = dynamicRequire('react-router');\n\n\t\treturn cachedReactRouter;\n\t} catch {\n\t\tconst fromWindow = (\n\t\t\tglobalThis as { ReactRouterDOM?: ReactRouterModule }\n\t\t).ReactRouterDOM;\n\t\tif (fromWindow) {\n\t\t\tcachedReactRouter = fromWindow;\n\n\t\t\treturn cachedReactRouter;\n\t\t}\n\t\tthrow new Error(\n\t\t\t'[UniversalRouter] react-router is not installed. Install it with `bun add react-router` to use UniversalRouter.'\n\t\t);\n\t}\n};\n\nexport const UniversalRouter = ({ url, children }: UniversalRouterProps) => {\n\tconst { BrowserRouter, StaticRouter } = loadReactRouter();\n\tif (typeof window === 'undefined') {\n\t\treturn createElement(StaticRouter, { location: url ?? '/' }, children);\n\t}\n\n\treturn createElement(BrowserRouter, null, children);\n};\n",
12
12
  "import { useSyncExternalStore } from 'react';\nimport type { StoreApi } from 'zustand/vanilla';\nimport {\n\tgetIslandStoreServerSnapshot,\n\treadIslandStore,\n\tsubscribeIslandStore,\n\ttype IslandStoreState\n} from '../../client/islandStore';\n\nexport const useIslandStore = <TState extends IslandStoreState, TSelected>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected\n) =>\n\tuseSyncExternalStore(\n\t\t(listener) =>\n\t\t\tsubscribeIslandStore(store, selector, () => {\n\t\t\t\tlistener();\n\t\t\t}),\n\t\t() => readIslandStore(store, selector),\n\t\t() => getIslandStoreServerSnapshot(store, selector)\n\t);\n",
13
13
  "const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n",
14
14
  "const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n",
@@ -42,7 +42,7 @@
42
42
  "import { basename } from 'node:path';\nimport type { ConventionsMap } from '../../types/conventions';\nimport { toPascal } from './stringModifiers';\n\n// Use globalThis so the conventions map is shared across all bundles.\n// The main bundle (dist/index.js) calls setConventions, but framework\n// bundles (dist/svelte/index.js, etc.) need to read the same map.\nconst CONVENTIONS_KEY = '__absoluteConventions';\n\nconst isConventionsMap = (value: unknown): value is ConventionsMap =>\n\tBoolean(value) && typeof value === 'object';\n\nconst getMap = () => {\n\tconst value: unknown = Reflect.get(globalThis, CONVENTIONS_KEY);\n\tif (isConventionsMap(value)) return value;\n\n\tconst empty: ConventionsMap = {};\n\n\treturn empty;\n};\n\nexport const derivePageName = (pagePath: string) => {\n\tconst base = basename(pagePath);\n\t// Strip hash and extension: \"SvelteExample.abc123.js\" → \"SvelteExample\"\n\tconst dotIndex = base.indexOf('.');\n\tconst name = dotIndex > 0 ? base.slice(0, dotIndex) : base;\n\n\treturn toPascal(name);\n};\nexport const getConventions = () => getMap();\n\nconst normalizeConventionPageName = (name: string) =>\n\ttoPascal(name).replace(/\\d+$/, '');\n\nexport const resolveErrorConventionPath = (\n\tframework: keyof ConventionsMap,\n\tpageName: string\n) => {\n\tconst conventions = getMap()[framework];\n\tif (!conventions) return undefined;\n\n\tconst exact = conventions.pages?.[pageName]?.error;\n\tif (exact) return exact;\n\n\tconst normalizedPageName = normalizeConventionPageName(pageName);\n\tfor (const [candidate, page] of Object.entries(conventions.pages ?? {})) {\n\t\tif (normalizeConventionPageName(candidate) === normalizedPageName) {\n\t\t\treturn page.error ?? conventions.defaults?.error;\n\t\t}\n\t}\n\n\treturn conventions.defaults?.error;\n};\nexport const resolveNotFoundConventionPath = (\n\tframework: keyof ConventionsMap\n) => getMap()[framework]?.defaults?.notFound;\n\nexport const hasErrorConvention = (framework: keyof ConventionsMap) => {\n\tconst conventions = getMap()[framework];\n\tif (!conventions) return false;\n\tif (conventions.defaults?.error) return true;\n\n\treturn Object.values(conventions.pages ?? {}).some((page) =>\n\t\tBoolean(page.error)\n\t);\n};\n\nexport const setConventions = (map: ConventionsMap) => {\n\tReflect.set(globalThis, CONVENTIONS_KEY, map);\n};\n\nconst isDev = () => process.env.NODE_ENV === 'development';\n\nconst buildErrorProps = (error: unknown) => {\n\tconst message = error instanceof Error ? error.message : String(error);\n\tconst stack = isDev() && error instanceof Error ? error.stack : undefined;\n\n\treturn { error: { message, stack } };\n};\n\nconst renderReactError = async (\n\tconventionPath: string,\n\terrorProps: ReturnType<typeof buildErrorProps>\n) => {\n\tconst { createElement } = await import('react');\n\tconst { renderToReadableStream } = await import('react-dom/server');\n\tconst mod = await import(conventionPath);\n\tconst [firstKey] = Object.keys(mod);\n\tconst ErrorComponent =\n\t\tmod.default ?? (firstKey ? mod[firstKey] : undefined);\n\tconst element = createElement(ErrorComponent, errorProps);\n\tconst stream = await renderToReadableStream(element);\n\n\treturn new Response(stream, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 500\n\t});\n};\n\nconst renderSvelteError = async (\n\tconventionPath: string,\n\terrorProps: ReturnType<typeof buildErrorProps>\n) => {\n\tconst { render } = await import('svelte/server');\n\tconst mod = await import(conventionPath);\n\tconst ErrorComponent = mod.default;\n\tconst { head, body } = render(ErrorComponent, {\n\t\tprops: errorProps\n\t});\n\tconst html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;\n\n\treturn new Response(html, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 500\n\t});\n};\n\nconst unescapeVueStyles = (ssrBody: string) => {\n\tlet styles = '';\n\tconst body = ssrBody.replace(\n\t\t/<style>([\\s\\S]*?)<\\/style>/g,\n\t\t(_, css: string) => {\n\t\t\tstyles += `<style>${css\n\t\t\t\t.replace(/&quot;/g, '\"')\n\t\t\t\t.replace(/&amp;/g, '&')\n\t\t\t\t.replace(/&lt;/g, '<')\n\t\t\t\t.replace(/&gt;/g, '>')}</style>`;\n\n\t\t\treturn '';\n\t\t}\n\t);\n\n\treturn { body, styles };\n};\n\nconst renderVueError = async (\n\tconventionPath: string,\n\terrorProps: ReturnType<typeof buildErrorProps>\n) => {\n\tconst { createSSRApp, h } = await import('vue');\n\tconst { renderToString } = await import('vue/server-renderer');\n\tconst mod = await import(conventionPath);\n\tconst ErrorComponent = mod.default;\n\tconst app = createSSRApp({\n\t\trender: () => h(ErrorComponent, errorProps)\n\t});\n\tconst rawBody = await renderToString(app);\n\n\t// Vue SSR escapes quotes inside <component is=\"style\"> tags.\n\t// Extract style content, unescape it, and move to <head>.\n\tconst { styles, body } = unescapeVueStyles(rawBody);\n\tconst html = `<!DOCTYPE html><html><head>${styles}</head><body><div id=\"root\">${body}</div></body></html>`;\n\n\treturn new Response(html, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 500\n\t});\n};\n\nconst renderAngularError = async (\n\tconventionPath: string,\n\terrorProps: ReturnType<typeof buildErrorProps>\n) => {\n\t// Angular error pages are rendered as plain HTML templates\n\t// since the full Angular SSR pipeline is too heavy for error pages\n\tconst mod = await import(conventionPath);\n\tconst renderError = mod.default ?? mod.renderError;\n\tif (typeof renderError !== 'function') return null;\n\n\tconst html = renderError(errorProps);\n\n\treturn new Response(html, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 500\n\t});\n};\n\nconst logConventionRenderError = (\n\tframework: keyof ConventionsMap,\n\tlabel: string,\n\trenderError: unknown\n) => {\n\tconst message = renderError instanceof Error ? renderError.message : '';\n\tif (\n\t\tmessage.includes('Cannot find module') ||\n\t\tmessage.includes('Cannot find package') ||\n\t\tmessage.includes('not found in module')\n\t) {\n\t\tconsole.error(\n\t\t\t`[SSR] Convention ${label} page for ${framework} failed: missing framework package. ` +\n\t\t\t\t`Ensure the ${framework} runtime is installed (e.g. bun add ${framework === 'react' ? 'react react-dom' : framework}).`\n\t\t);\n\n\t\treturn;\n\t}\n\n\tconsole.error(\n\t\t`[SSR] Failed to render ${framework} convention ${label} page:`,\n\t\trenderError\n\t);\n};\n\n// Phase 1 Ember adapter: convention pages aren't wired yet (no\n// renderEmberError analog ships in v1). Returning null falls through to\n// the generic ssrErrorPage. Phase 1.5 replaces this stub with a real\n// renderer once the convention scanner knows about .gjs/.gts files.\nconst renderEmberError = async () => null;\nconst renderEmberNotFound = async () => null;\n\nconst ERROR_RENDERERS: Record<\n\tkeyof ConventionsMap,\n\t(\n\t\tconventionPath: string,\n\t\terrorProps: ReturnType<typeof buildErrorProps>\n\t) => Promise<Response | null>\n> = {\n\tangular: renderAngularError,\n\tember: renderEmberError,\n\treact: renderReactError,\n\tsvelte: renderSvelteError,\n\tvue: renderVueError\n};\n\nexport const renderConventionError = async (\n\tframework: keyof ConventionsMap,\n\tpageName: string,\n\terror: unknown\n) => {\n\tlet conventionPath = resolveErrorConventionPath(framework, pageName);\n\tif (!conventionPath && error instanceof Error && error.stack) {\n\t\tfor (const match of error.stack.matchAll(\n\t\t\t/^\\s*at\\s+([A-Za-z_$][\\w$]*)/gm\n\t\t)) {\n\t\t\tconst candidate = match[1];\n\t\t\tif (!candidate) continue;\n\n\t\t\tconventionPath = resolveErrorConventionPath(framework, candidate);\n\t\t\tif (conventionPath) break;\n\t\t}\n\t}\n\tif (!conventionPath) return null;\n\n\tconst errorProps = buildErrorProps(error);\n\tconst renderer = ERROR_RENDERERS[framework];\n\tif (!renderer) return null;\n\n\ttry {\n\t\treturn await renderer(conventionPath, errorProps);\n\t} catch (renderError) {\n\t\tlogConventionRenderError(framework, 'error', renderError);\n\t}\n\n\treturn null;\n};\n\nconst renderReactNotFound = async (conventionPath: string) => {\n\tconst { createElement } = await import('react');\n\tconst { renderToReadableStream } = await import('react-dom/server');\n\tconst mod = await import(conventionPath);\n\tconst [nfKey] = Object.keys(mod);\n\tconst NotFoundComponent = mod.default ?? (nfKey ? mod[nfKey] : undefined);\n\tconst element = createElement(NotFoundComponent);\n\tconst stream = await renderToReadableStream(element);\n\n\treturn new Response(stream, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 404\n\t});\n};\n\nconst renderSvelteNotFound = async (conventionPath: string) => {\n\tconst { render } = await import('svelte/server');\n\tconst mod = await import(conventionPath);\n\tconst NotFoundComponent = mod.default;\n\tconst { head, body } = render(NotFoundComponent);\n\tconst html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;\n\n\treturn new Response(html, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 404\n\t});\n};\n\nconst renderVueNotFound = async (conventionPath: string) => {\n\tconst { createSSRApp, h } = await import('vue');\n\tconst { renderToString } = await import('vue/server-renderer');\n\tconst mod = await import(conventionPath);\n\tconst NotFoundComponent = mod.default;\n\tconst app = createSSRApp({\n\t\trender: () => h(NotFoundComponent)\n\t});\n\tconst rawBody = await renderToString(app);\n\n\tconst { styles, body } = unescapeVueStyles(rawBody);\n\tconst html = `<!DOCTYPE html><html><head>${styles}</head><body><div id=\"root\">${body}</div></body></html>`;\n\n\treturn new Response(html, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 404\n\t});\n};\n\nconst renderAngularNotFound = async (conventionPath: string) => {\n\tconst mod = await import(conventionPath);\n\tconst renderNotFound = mod.default ?? mod.renderNotFound;\n\tif (typeof renderNotFound !== 'function') return null;\n\n\tconst html = renderNotFound();\n\n\treturn new Response(html, {\n\t\theaders: { 'Content-Type': 'text/html' },\n\t\tstatus: 404\n\t});\n};\n\nconst NOT_FOUND_RENDERERS: Record<\n\tkeyof ConventionsMap,\n\t(conventionPath: string) => Promise<Response | null>\n> = {\n\tangular: renderAngularNotFound,\n\tember: renderEmberNotFound,\n\treact: renderReactNotFound,\n\tsvelte: renderSvelteNotFound,\n\tvue: renderVueNotFound\n};\n\nexport const renderConventionNotFound = async (\n\tframework: keyof ConventionsMap\n) => {\n\tconst conventionPath = resolveNotFoundConventionPath(framework);\n\tif (!conventionPath) return null;\n\n\tconst renderer = NOT_FOUND_RENDERERS[framework];\n\tif (!renderer) return null;\n\n\ttry {\n\t\treturn await renderer(conventionPath);\n\t} catch (renderError) {\n\t\tlogConventionRenderError(framework, 'not-found', renderError);\n\t}\n\n\treturn null;\n};\n\nconst NOT_FOUND_PRIORITY: (keyof ConventionsMap)[] = [\n\t'react',\n\t'svelte',\n\t'vue',\n\t'angular'\n];\n\nexport const renderFirstNotFound = async () => {\n\tconst renderNext = async (frameworks: (keyof ConventionsMap)[]) => {\n\t\tconst [framework, ...remaining] = frameworks;\n\t\tif (!framework) {\n\t\t\treturn null;\n\t\t}\n\t\tif (!getMap()[framework]?.defaults?.notFound) {\n\t\t\treturn renderNext(remaining);\n\t\t}\n\n\t\tconst response = await renderConventionNotFound(framework);\n\t\tif (response) {\n\t\t\treturn response;\n\t\t}\n\n\t\treturn renderNext(remaining);\n\t};\n\n\treturn renderNext(NOT_FOUND_PRIORITY);\n};\n",
43
43
  "import type { RuntimeIslandRenderProps } from '../../types/island';\nimport { getIslandMarkerAttributes } from '../core/islandMarkupAttributes';\nimport { requireCurrentIslandRegistry } from '../core/currentIslandRegistry';\nimport { renderIslandResult } from '../core/renderIslandMarkup';\n\nexport const Island = async (props: RuntimeIslandRenderProps) => {\n\tif (typeof window !== 'undefined') {\n\t\treturn (\n\t\t\t<div\n\t\t\t\t{...getIslandMarkerAttributes(props)}\n\t\t\t\tsuppressHydrationWarning\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst result = await renderIslandResult(\n\t\trequireCurrentIslandRegistry(),\n\t\tprops\n\t);\n\n\treturn (\n\t\t<div\n\t\t\t{...result.attributes}\n\t\t\tdangerouslySetInnerHTML={{ __html: result.html }}\n\t\t/>\n\t);\n};\n",
44
44
  "import type {\n\tIslandRegistry,\n\tIslandRegistryInput,\n\tTypedIslandRenderProps\n} from '../../types/island';\nimport { getIslandMarkerAttributes } from '../core/islandMarkupAttributes';\nimport { renderIslandResult } from '../core/renderIslandMarkup';\n\nexport const createTypedIsland = <T extends IslandRegistryInput>(\n\tregistry: IslandRegistry<T>\n) => {\n\tconst Island = async (props: TypedIslandRenderProps<T>) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\treturn (\n\t\t\t\t<div\n\t\t\t\t\t{...getIslandMarkerAttributes(props)}\n\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\t\tconst result = await renderIslandResult(registry, props);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\t{...result.attributes}\n\t\t\t\tdangerouslySetInnerHTML={{ __html: result.html }}\n\t\t\t/>\n\t\t);\n\t};\n\n\treturn Island;\n};\n",
45
- "import { createElement, type ReactNode } from 'react';\n\nexport type UniversalRouterProps = {\n\t/** The request URL to seed `<StaticRouter>` with on the server. Pages\n\t * typically forward `props.url` (auto-injected by handleReactPageRequest\n\t * from `request.url`). Ignored in the browser, where `<BrowserRouter>`\n\t * reads `window.location` directly. Defaults to '/'. */\n\turl?: string;\n\tchildren?: ReactNode;\n};\n\n/** SSR-safe wrapper around react-router that picks `<StaticRouter>` on the\n * server and `<BrowserRouter>` in the browser. Without it, every SPA page\n * has to write its own `typeof window === 'undefined'` branch and import\n * both routers — boilerplate that's the same in every page.\n *\n * Usage:\n *\n * export const MySpa = ({ url }: { url?: string }) => (\n * <html>\n * <Head />\n * <body>\n * <UniversalRouter url={url}>\n * <Routes>\n * <Route path=\"/foo\" element={<Foo />} />\n * </Routes>\n * </UniversalRouter>\n * </body>\n * </html>\n * );\n *\n * Implementation note: `react-router` is required lazily via\n * `createRequire` so consumers who don't use `UniversalRouter` aren't\n * forced to install react-router just to import other things from\n * `@absolutejs/absolute/react` (the previous eager static import made\n * `dist/react/index.js` carry a `import \"react-router\"` that broke\n * every consumer's bundle who hadn't installed it). Bun resolves the\n * CJS interop synchronously, so render is still purely synchronous.\n *\n * `<BrowserRouter>` reads `window.history` at construction, so it\n * throws if instantiated on the server. The `typeof window` check has\n * to live at render time (not import time) because the module is\n * loaded in both environments. */\n\ntype ReactRouterModule = {\n\tBrowserRouter: (...args: unknown[]) => unknown;\n\tStaticRouter: (...args: unknown[]) => unknown;\n};\n\nlet cachedReactRouter: ReactRouterModule | null = null;\n\nconst loadReactRouter = (): ReactRouterModule => {\n\tif (cachedReactRouter) return cachedReactRouter;\n\n\t// Hide the bare specifier behind a Function-constructor so static\n\t// bundlers can't analyze it — they only see a `Function(string)`\n\t// call, not an `import \"react-router\"`. Resolution happens at\n\t// render time and only on the first call to `UniversalRouter`,\n\t// so consumers who never use it never pay the install cost.\n\t// `require` is available in Bun's CJS-interop context (server)\n\t// and in any bundle output that emitted a CJS-compatible runtime.\n\ttry {\n\t\tconst dynamicRequire = new Function('spec', 'return require(spec)') as (\n\t\t\tspec: string\n\t\t) => ReactRouterModule;\n\t\tcachedReactRouter = dynamicRequire('react-router');\n\n\t\treturn cachedReactRouter;\n\t} catch {\n\t\tconst fromWindow = (\n\t\t\tglobalThis as { ReactRouterDOM?: ReactRouterModule }\n\t\t).ReactRouterDOM;\n\t\tif (fromWindow) {\n\t\t\tcachedReactRouter = fromWindow;\n\n\t\t\treturn cachedReactRouter;\n\t\t}\n\t\tthrow new Error(\n\t\t\t'[UniversalRouter] react-router is not installed. Install it with `bun add react-router` to use UniversalRouter.'\n\t\t);\n\t}\n};\n\nexport const UniversalRouter = ({ url, children }: UniversalRouterProps) => {\n\tconst { BrowserRouter, StaticRouter } = loadReactRouter();\n\tif (typeof window === 'undefined') {\n\t\treturn createElement(StaticRouter, { location: url ?? '/' }, children);\n\t}\n\n\treturn createElement(BrowserRouter, null, children);\n};\n",
45
+ "import { createElement, type ComponentType, type ReactNode } from 'react';\n\nexport type UniversalRouterProps = {\n\t/** The request URL to seed `<StaticRouter>` with on the server. Pages\n\t * typically forward `props.url` (auto-injected by handleReactPageRequest\n\t * from `request.url`). Ignored in the browser, where `<BrowserRouter>`\n\t * reads `window.location` directly. Defaults to '/'. */\n\turl?: string;\n\tchildren?: ReactNode;\n};\n\n/** SSR-safe wrapper around react-router that picks `<StaticRouter>` on the\n * server and `<BrowserRouter>` in the browser. Without it, every SPA page\n * has to write its own `typeof window === 'undefined'` branch and import\n * both routers — boilerplate that's the same in every page.\n *\n * Usage:\n *\n * export const MySpa = ({ url }: { url?: string }) => (\n * <html>\n * <Head />\n * <body>\n * <UniversalRouter url={url}>\n * <Routes>\n * <Route path=\"/foo\" element={<Foo />} />\n * </Routes>\n * </UniversalRouter>\n * </body>\n * </html>\n * );\n *\n * Implementation note: `react-router` is required lazily via\n * `createRequire` so consumers who don't use `UniversalRouter` aren't\n * forced to install react-router just to import other things from\n * `@absolutejs/absolute/react` (the previous eager static import made\n * `dist/react/index.js` carry a `import \"react-router\"` that broke\n * every consumer's bundle who hadn't installed it). Bun resolves the\n * CJS interop synchronously, so render is still purely synchronous.\n *\n * `<BrowserRouter>` reads `window.history` at construction, so it\n * throws if instantiated on the server. The `typeof window` check has\n * to live at render time (not import time) because the module is\n * loaded in both environments. */\n\ntype ReactRouterModule = {\n\tBrowserRouter: ComponentType<{ children?: ReactNode }>;\n\tStaticRouter: ComponentType<{ location: string; children?: ReactNode }>;\n};\n\nlet cachedReactRouter: ReactRouterModule | null = null;\n\nconst loadReactRouter = (): ReactRouterModule => {\n\tif (cachedReactRouter) return cachedReactRouter;\n\n\t// Hide the bare specifier behind a Function-constructor so static\n\t// bundlers can't analyze it — they only see a `Function(string)`\n\t// call, not an `import \"react-router\"`. Resolution happens at\n\t// render time and only on the first call to `UniversalRouter`,\n\t// so consumers who never use it never pay the install cost.\n\t// `require` is available in Bun's CJS-interop context (server)\n\t// and in any bundle output that emitted a CJS-compatible runtime.\n\ttry {\n\t\tconst dynamicRequire = new Function('spec', 'return require(spec)') as (\n\t\t\tspec: string\n\t\t) => ReactRouterModule;\n\t\tcachedReactRouter = dynamicRequire('react-router');\n\n\t\treturn cachedReactRouter;\n\t} catch {\n\t\tconst fromWindow = (\n\t\t\tglobalThis as { ReactRouterDOM?: ReactRouterModule }\n\t\t).ReactRouterDOM;\n\t\tif (fromWindow) {\n\t\t\tcachedReactRouter = fromWindow;\n\n\t\t\treturn cachedReactRouter;\n\t\t}\n\t\tthrow new Error(\n\t\t\t'[UniversalRouter] react-router is not installed. Install it with `bun add react-router` to use UniversalRouter.'\n\t\t);\n\t}\n};\n\nexport const UniversalRouter = ({ url, children }: UniversalRouterProps) => {\n\tconst { BrowserRouter, StaticRouter } = loadReactRouter();\n\tif (typeof window === 'undefined') {\n\t\treturn createElement(StaticRouter, { location: url ?? '/' }, children);\n\t}\n\n\treturn createElement(BrowserRouter, null, children);\n};\n",
46
46
  "import { useSyncExternalStore } from 'react';\nimport type { StoreApi } from 'zustand/vanilla';\nimport {\n\tgetIslandStoreServerSnapshot,\n\treadIslandStore,\n\tsubscribeIslandStore,\n\ttype IslandStoreState\n} from '../../client/islandStore';\n\nexport const useIslandStore = <TState extends IslandStoreState, TSelected>(\n\tstore: StoreApi<TState>,\n\tselector: (state: TState) => TSelected\n) =>\n\tuseSyncExternalStore(\n\t\t(listener) =>\n\t\t\tsubscribeIslandStore(store, selector, () => {\n\t\t\t\tlistener();\n\t\t\t}),\n\t\t() => readIslandStore(store, selector),\n\t\t() => getIslandStoreServerSnapshot(store, selector)\n\t);\n",
47
47
  "const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n",
48
48
  "const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n",
@@ -7,4 +7,6 @@ export type UniversalRouterProps = {
7
7
  url?: string;
8
8
  children?: ReactNode;
9
9
  };
10
- export declare const UniversalRouter: ({ url, children }: UniversalRouterProps) => import("react").DetailedReactHTMLElement<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
10
+ export declare const UniversalRouter: ({ url, children }: UniversalRouterProps) => import("react").ReactElement<{
11
+ children?: ReactNode;
12
+ }, string | import("react").JSXElementConstructor<any>>;
@@ -67,15 +67,6 @@ declare global {
67
67
  __ANGULAR_HMR__?: {
68
68
  register: (id: string, ctor: unknown) => void;
69
69
  applyUpdate: (id: string, newCtor: unknown) => boolean;
70
- applyStyleUpdate: (id: string, newCtor: unknown) => boolean;
71
- applyTemplateUpdate: (id: string, newCtor: unknown) => boolean;
72
- applyServiceUpdate: (id: string, newCtor: unknown) => boolean;
73
- beginStyleUpdateBatch: () => void;
74
- endStyleUpdateBatch: () => Array<{ id: string; ok: boolean }>;
75
- beginTemplateUpdateBatch: () => void;
76
- endTemplateUpdateBatch: () => Array<{ id: string; ok: boolean }>;
77
- beginServiceUpdateBatch: () => void;
78
- endServiceUpdateBatch: () => Array<{ id: string; ok: boolean }>;
79
70
  refresh: () => void;
80
71
  getStats: () => { componentCount: number; updateCount: number };
81
72
  getRegistry: () => Map<
@@ -94,9 +85,6 @@ declare global {
94
85
  ) => void;
95
86
  hasPageExportsChanged: (sourceId: string) => boolean;
96
87
  };
97
- __ANGULAR_HMR_STYLE_UPDATE_MODE__?: boolean;
98
- __ANGULAR_HMR_TEMPLATE_UPDATE_MODE__?: boolean;
99
- __ANGULAR_HMR_SERVICE_UPDATE_MODE__?: boolean;
100
88
  __VUE_APP__?:
101
89
  | ({
102
90
  unmount: () => void;
package/package.json CHANGED
@@ -384,5 +384,5 @@
384
384
  ]
385
385
  }
386
386
  },
387
- "version": "0.19.0-beta.850"
387
+ "version": "0.19.0-beta.852"
388
388
  }