@absolutejs/absolute 0.19.0-beta.851 → 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-64JFeG/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-64JFeG/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-64JFeG/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,237 +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
- // Empty batch = the chunk's components weren't already in the
406
- // registry (off-page broadcast). No-op success — see the
407
- // matching comment in `handleComponentStyleUpdate`.
408
- if (results.length === 0) {
409
- console.warn = origWarn;
410
- return true;
411
- }
412
- if (!results.every((r) => r.ok)) return false;
413
-
414
- console.warn = origWarn;
415
- hmr.refresh();
416
-
417
- return true;
418
- } catch (err) {
419
- console.warn = origWarn;
420
- console.warn(
421
- '[HMR] Angular template update failed, falling back:',
422
- err
423
- );
424
- return false;
425
- } finally {
426
- delete w.__ANGULAR_HMR_FAST_PATCH__;
427
- delete w.__ANGULAR_HMR_TEMPLATE_UPDATE_MODE__;
428
- console.warn = origWarn;
429
- }
430
- };
431
-
432
- /* Component-style HMR — re-imports the rebuilt page chunk under the
433
- * combined `FAST_PATCH` and `STYLE_UPDATE_MODE` flags so:
434
- * - the chunk's bootstrap section is skipped (FAST_PATCH)
435
- * - every per-file auto-registration block routes its new ctor
436
- * through `applyStyleUpdate` instead of a no-op (STYLE_UPDATE_MODE)
437
- *
438
- * The registration-block path is the only way to reach CHILD
439
- * components — the page chunk's `export *` only re-exports the page's
440
- * own module, so a top-level export walk would miss imported
441
- * components like `LayoutComponent`. Each compiled .ts file emits a
442
- * registration block for its own component classes, so the chunk
443
- * covers the whole tree on re-evaluation.
444
- *
445
- * Returns true iff every component the chunk re-registered swapped
446
- * its styles cleanly. Any failure (Shadow DOM, length change, missing
447
- * live <style> tag) → reboot. The transactional check inside
448
- * `applyStyleUpdate` means we never apply a partial update — either
449
- * the page restyles coherently or we reboot. */
450
- type StyleUpdateWindow = FastPatchWindow & {
451
- __ANGULAR_HMR_STYLE_UPDATE_MODE__?: boolean;
452
- };
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;
453
357
 
454
358
  const handleComponentStyleUpdate = async (
455
- message: HMRMessage
456
- ): Promise<boolean> => {
457
- const hmr = window.__ANGULAR_HMR__;
458
- if (
459
- !hmr ||
460
- !hmr.applyStyleUpdate ||
461
- !hmr.beginStyleUpdateBatch ||
462
- !hmr.endStyleUpdateBatch
463
- ) {
464
- return false;
465
- }
466
-
467
- const indexPath = findIndexPath(
468
- message.data.manifest,
469
- message.data.sourceFile,
470
- 'angular'
471
- );
472
- if (!indexPath) return false;
473
-
474
- const w = window as StyleUpdateWindow;
475
- w.__ANGULAR_HMR_FAST_PATCH__ = true;
476
- w.__ANGULAR_HMR_STYLE_UPDATE_MODE__ = true;
477
- hmr.beginStyleUpdateBatch();
478
-
479
- try {
480
- await import(`${indexPath}?t=${Date.now()}`);
481
-
482
- // Page-level routes/providers cannot ride a style update — they
483
- // are read once during bootstrap. If they changed in this
484
- // rebuild, reboot rather than risk a stale router/injector.
485
- if (hmr.hasPageExportsChanged?.(message.data.sourceFile || '')) {
486
- return false;
487
- }
488
-
489
- const results = hmr.endStyleUpdateBatch();
490
- // Empty batch is a no-op success: the chunk re-evaluated but
491
- // none of its components were already in the registry, so they
492
- // couldn't be live on the page right now. Common when a CSS
493
- // edit affects multiple page bundles (the server broadcasts
494
- // once per page) and the user is only looking at one of them —
495
- // the off-page broadcasts add fresh entries to the registry but
496
- // produce no batch updates. Treating that as a failure forced
497
- // fallthrough to reboot for every off-page broadcast, which
498
- // fired `startViewTransition` repeatedly and produced the
499
- // "Transition was skipped" abort when the second reboot
500
- // superseded the first mid-flight.
501
- if (results.length === 0) return true;
502
- return results.every((r) => r.ok);
503
- } catch (err) {
504
- console.warn('[HMR] Angular style update failed, falling back:', err);
505
- return false;
506
- } finally {
507
- delete w.__ANGULAR_HMR_FAST_PATCH__;
508
- delete w.__ANGULAR_HMR_STYLE_UPDATE_MODE__;
509
- }
510
- };
511
-
512
- /* Service HMR — re-imports the rebuilt page chunk under FAST_PATCH +
513
- * SERVICE_UPDATE_MODE so the page's auto-registration block routes
514
- * each new service ctor through `applyServiceUpdate`. The runtime
515
- * does prototype method-swap (always) and best-effort field merge on
516
- * the live singleton (when reachable via the root injector and
517
- * donor-instantiable). Live components keep their references — they
518
- * just call into the new method bodies on next invocation.
519
- *
520
- * This path only runs when the server-side classifier returned
521
- * `service-method-only` — services with side-effecting constructors
522
- * never get here, so the live singleton's existing subscriptions /
523
- * timers / listeners stay intact and we don't double-register them. */
524
- type ServiceUpdateWindow = FastPatchWindow & {
525
- __ANGULAR_HMR_SERVICE_UPDATE_MODE__?: boolean;
526
- };
359
+ _message: HMRMessage
360
+ ): Promise<boolean> => false;
527
361
 
528
362
  const handleServiceMethodSwap = async (
529
- message: HMRMessage
530
- ): Promise<boolean> => {
531
- const hmr = window.__ANGULAR_HMR__;
532
- if (
533
- !hmr ||
534
- !hmr.applyServiceUpdate ||
535
- !hmr.beginServiceUpdateBatch ||
536
- !hmr.endServiceUpdateBatch
537
- ) {
538
- return false;
539
- }
540
-
541
- const indexPath = findIndexPath(
542
- message.data.manifest,
543
- message.data.sourceFile,
544
- 'angular'
545
- );
546
- if (!indexPath) return false;
547
-
548
- const w = window as ServiceUpdateWindow;
549
- w.__ANGULAR_HMR_FAST_PATCH__ = true;
550
- w.__ANGULAR_HMR_SERVICE_UPDATE_MODE__ = true;
551
- hmr.beginServiceUpdateBatch();
552
-
553
- try {
554
- await import(`${indexPath}?t=${Date.now()}`);
555
-
556
- // Page-level routes/providers cannot ride a service update.
557
- if (hmr.hasPageExportsChanged?.(message.data.sourceFile || '')) {
558
- return false;
559
- }
560
-
561
- const results = hmr.endServiceUpdateBatch();
562
- // Empty batch = off-page broadcast, see comment in
563
- // `handleComponentStyleUpdate`.
564
- if (results.length === 0) return true;
565
- if (!results.every((r) => r.ok)) return false;
566
-
567
- // New method bodies might compute new values for observable-fed
568
- // fields, so the existing component subtree should re-render.
569
- // `refresh()` ticks the app + marks any pending fast-patch
570
- // components dirty.
571
- hmr.refresh();
572
-
573
- return true;
574
- } catch (err) {
575
- console.warn('[HMR] Angular service update failed, falling back:', err);
576
- return false;
577
- } finally {
578
- delete w.__ANGULAR_HMR_FAST_PATCH__;
579
- delete w.__ANGULAR_HMR_SERVICE_UPDATE_MODE__;
580
- }
581
- };
363
+ _message: HMRMessage
364
+ ): Promise<boolean> => false;
582
365
 
583
366
  const logRebootReason = (message: HMRMessage) => {
584
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,391 +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
- // Always update `ɵcmp.styles` first so future mounts of this
457
- // component pick up the new content. The DOM `<style>` swap below
458
- // handles currently-mounted instances; any component that isn't on
459
- // the page right now (an unopened modal, a route view that hasn't
460
- // been visited yet) simply has no `<style>` tag to find — and
461
- // that's fine. The next time it mounts, Angular reads from
462
- // `ɵcmp.styles` and injects the new content. Treating that case
463
- // as a failure was the source of the "Transition was skipped"
464
- // bug: the SPA at /portal/dashboard registered dozens of
465
- // components whose styles weren't injected (modals, sibling tabs,
466
- // etc.), and each missing live `<style>` tag forced fallthrough
467
- // to the reboot path, firing `startViewTransition` while the
468
- // previous one was still finishing.
469
- liveCmp.styles = nextStyles;
470
-
471
- const hosts = collectStyleHosts();
472
- const consumed = new Set<HTMLStyleElement>();
473
-
474
- for (let i = 0; i < oldStyles.length; i++) {
475
- const oldContent = oldStyles[i] ?? '';
476
- const nextContent = nextStyles[i] ?? '';
477
- if (oldContent === nextContent) continue;
478
- const tag = findStyleTagByContent(hosts, oldContent, consumed);
479
- if (!tag) {
480
- // Component not currently mounted (or already-swapped style).
481
- // Skip the DOM swap; `ɵcmp.styles` is already updated above
482
- // so the next mount picks up the new content.
483
- continue;
484
- }
485
- consumed.add(tag);
486
- tag.textContent = nextContent;
487
- }
488
-
489
- updateCounter.value++;
490
- entry.updateCount++;
491
- entry.registeredAt = Date.now();
492
-
493
- return true;
494
- };
495
-
496
- /* Template HMR — surgical swap of the template-related fields on a
497
- * registered component's `ɵcmp` so the live instance re-renders with
498
- * the new template WITHOUT re-instantiating. Inputs, outputs, host
499
- * bindings, providers, and lifecycle hooks live on the class
500
- * prototype + ɵcmp, and we leave those alone — only the template
501
- * factory and the slot counts/queries that depend on it are replaced.
502
- *
503
- * Why a defined list of fields and not a full `ɵcmp` swap: a wholesale
504
- * `Object.assign(liveCmp, newCmp)` would also overwrite `providers /
505
- * providersResolver` and other class-level metadata. Those changes
506
- * already require a full reboot (the existing fast-path handler in
507
- * `angular.ts` checks `hasProviderChanges` and bails). For a pure
508
- * template edit, restricting the patch to the template subgraph
509
- * keeps live instances on the same DI tokens, queryList references,
510
- * input bindings, etc. — only the rendered output changes.
511
- *
512
- * After the swap, the component's TView (the cached view layout) is
513
- * stale because slot counts may have changed. Angular regenerates the
514
- * TView lazily on the first re-render, but only if the existing one
515
- * is invalidated — which happens automatically when we walk the live
516
- * instances and call `applyChanges`. The same `markPatchedDirty`
517
- * helper used by `applyUpdate` covers OnPush views too. */
518
-
519
- const TEMPLATE_PATCH_FIELDS = [
520
- 'template',
521
- 'consts',
522
- 'decls',
523
- 'vars',
524
- 'viewQuery',
525
- 'contentQueries',
526
- 'ngContentSelectors',
527
- 'dependencies',
528
- 'hostBindings',
529
- 'hostVars',
530
- 'hostAttrs',
531
- 'inputs',
532
- 'outputs'
533
- ] as const;
534
-
535
- const applyTemplateUpdate = (id: string, newCtor: unknown) => {
536
- if (!isComponentCtor(newCtor)) return false;
537
-
538
- const entry = componentRegistry.get(id);
539
- if (!entry) {
540
- register(id, newCtor);
541
-
542
- return true;
543
- }
544
-
545
- const { liveCtor } = entry;
546
- if (liveCtor === newCtor) return true;
547
-
548
- const liveCmp = liveCtor.ɵcmp as Record<string, unknown> | undefined;
549
- const nextCmp = newCtor.ɵcmp as Record<string, unknown> | undefined;
550
- if (!liveCmp || !nextCmp) return false;
551
-
552
- // If providers changed, this isn't a pure template edit anymore —
553
- // fall back to reboot via the caller.
554
- if (hasProviderChanges(liveCtor, newCtor)) return false;
555
-
556
- for (const field of TEMPLATE_PATCH_FIELDS) {
557
- if (Object.prototype.hasOwnProperty.call(nextCmp, field)) {
558
- liveCmp[field] = nextCmp[field];
559
- }
560
- }
561
-
562
- pendingFastPatchRefresh.add(liveCtor);
563
- updateCounter.value++;
564
- entry.updateCount++;
565
- entry.registeredAt = Date.now();
566
-
567
- return true;
568
- };
569
-
570
- type TemplateUpdateMode = typeof globalThis & {
571
- __ANGULAR_HMR_TEMPLATE_UPDATE_MODE__?: boolean;
572
- };
573
-
574
- const templateUpdateBatch: StyleBatchEntry[] = [];
575
-
576
- const beginTemplateUpdateBatch = () => {
577
- templateUpdateBatch.length = 0;
578
- };
579
-
580
- const endTemplateUpdateBatch = (): StyleBatchEntry[] => {
581
- const out = templateUpdateBatch.slice();
582
- templateUpdateBatch.length = 0;
583
-
584
- return out;
585
- };
586
-
587
- /* Service HMR — Level 3 hybrid:
588
- * 1. Always swap prototype methods on the live ctor. Reaches every
589
- * live instance (singletons + transient injectees) because they
590
- * all share the same prototype.
591
- * 2. If the live singleton is reachable via the root injector,
592
- * attempt to instantiate a donor with the new ctor and copy any
593
- * OWN PROPERTIES that the live singleton is missing — this picks
594
- * up new class-field initializers without overwriting accumulated
595
- * runtime state. Donor instantiation is best-effort: services
596
- * using `inject()` outside of an injection context will throw,
597
- * and we just skip the field merge in that case (the prototype
598
- * swap still applies, so method changes take effect).
599
- * 3. The classifier only routes here for services with NO
600
- * side-effecting calls in the constructor / field initializers
601
- * (no `subscribe / setInterval / addEventListener / effect /
602
- * new Worker / new EventSource / etc.`). Anything that touches
603
- * external state at construction time falls through to reboot
604
- * via the server-side classification, never reaching this code
605
- * path. */
606
-
607
- type AppRefWithInjector = {
608
- injector?: { get?: (token: unknown, notFoundValue?: unknown) => unknown };
609
- };
610
-
611
- const getRootInjector = (): {
612
- get: (token: unknown, notFoundValue?: unknown) => unknown;
613
- } | null => {
614
- const app = window.__ANGULAR_APP__ as AppRefWithInjector | null;
615
- if (!app || !app.injector || typeof app.injector.get !== 'function') {
616
- return null;
617
- }
618
-
619
- return app.injector as {
620
- get: (token: unknown, notFoundValue?: unknown) => unknown;
621
- };
622
- };
623
-
624
- const swapPrototypeMethods = (
625
- liveCtor: ComponentCtor,
626
- newCtor: ComponentCtor
627
- ) => {
628
- const newProto = newCtor.prototype as Record<string, unknown>;
629
- const liveProto = liveCtor.prototype as Record<string, unknown>;
630
- Object.getOwnPropertyNames(newProto).forEach((prop) => {
631
- if (prop === 'constructor') return;
632
- try {
633
- const desc = Object.getOwnPropertyDescriptor(newProto, prop);
634
- if (desc) Object.defineProperty(liveProto, prop, desc);
635
- } catch {
636
- /* non-configurable property — skip */
637
- }
638
- });
639
- };
640
-
641
- const tryInstantiateServiceDonor = (newCtor: ComponentCtor): unknown | null => {
642
- try {
643
- // `new newCtor()` with no args. Works for services with no
644
- // constructor params and no `inject()` calls at field-init time.
645
- // Anything more sophisticated (services that use `inject()`
646
- // outside an injection context) throws here and we fall back to
647
- // prototype-only swap.
648
- return Reflect.construct(newCtor as unknown as new () => unknown, []);
649
- } catch {
650
- return null;
651
- }
652
- };
653
-
654
- const mergeMissingFields = (
655
- liveInstance: Record<string, unknown>,
656
- donor: Record<string, unknown>
657
- ) => {
658
- let merged = 0;
659
- Object.getOwnPropertyNames(donor).forEach((prop) => {
660
- if (Object.prototype.hasOwnProperty.call(liveInstance, prop)) return;
661
- try {
662
- const desc = Object.getOwnPropertyDescriptor(donor, prop);
663
- if (desc) {
664
- Object.defineProperty(liveInstance, prop, desc);
665
- merged++;
666
- }
667
- } catch {
668
- /* defining the property failed — skip */
669
- }
670
- });
671
-
672
- return merged;
673
- };
674
-
675
- const applyServiceUpdate = (id: string, newCtor: unknown) => {
676
- if (!isComponentCtor(newCtor)) return false;
677
-
678
- const entry = componentRegistry.get(id);
679
- if (!entry) {
680
- register(id, newCtor);
681
-
682
- return true;
683
- }
684
-
685
- const { liveCtor } = entry;
686
- if (liveCtor === newCtor) return true;
687
-
688
- // Method swap — reaches every live instance.
689
- swapPrototypeMethods(liveCtor, newCtor);
690
-
691
- // Best-effort field merge on the live singleton.
692
- const injector = getRootInjector();
693
- if (injector) {
694
- try {
695
- const liveInstance = injector.get(liveCtor, null) as Record<
696
- string,
697
- unknown
698
- > | null;
699
- if (liveInstance) {
700
- const donor = tryInstantiateServiceDonor(newCtor) as Record<
701
- string,
702
- unknown
703
- > | null;
704
- if (donor) mergeMissingFields(liveInstance, donor);
705
- }
706
- } catch {
707
- /* injector lookup failed — service may not be `providedIn:
708
- "root"`, or the type-token mismatched. Prototype swap is
709
- already applied, so methods take effect either way. */
710
- }
711
- }
712
-
713
- updateCounter.value++;
714
- entry.updateCount++;
715
- entry.registeredAt = Date.now();
716
-
717
- return true;
718
- };
719
-
720
- type ServiceUpdateMode = typeof globalThis & {
721
- __ANGULAR_HMR_SERVICE_UPDATE_MODE__?: boolean;
722
- };
723
-
724
- const serviceUpdateBatch: StyleBatchEntry[] = [];
725
-
726
- const beginServiceUpdateBatch = () => {
727
- serviceUpdateBatch.length = 0;
728
- };
729
-
730
- const endServiceUpdateBatch = (): StyleBatchEntry[] => {
731
- const out = serviceUpdateBatch.slice();
732
- serviceUpdateBatch.length = 0;
733
-
734
- return out;
735
- };
736
-
737
270
  const applyUpdate = (id: string, newCtor: unknown) => {
738
271
  if (!isComponentCtor(newCtor)) return false;
739
272
 
@@ -869,16 +402,7 @@ const hasPageExportsChanged = (sourceId: string): boolean => {
869
402
  export const installAngularHMRRuntime = () => {
870
403
  if (typeof window === 'undefined') return;
871
404
  window.__ANGULAR_HMR__ = {
872
- applyServiceUpdate,
873
- applyStyleUpdate,
874
- applyTemplateUpdate,
875
405
  applyUpdate,
876
- beginServiceUpdateBatch,
877
- beginStyleUpdateBatch,
878
- beginTemplateUpdateBatch,
879
- endServiceUpdateBatch,
880
- endStyleUpdateBatch,
881
- endTemplateUpdateBatch,
882
406
  getStats: getAngularHmrStats,
883
407
  hasPageExportsChanged,
884
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.851"
387
+ "version": "0.19.0-beta.852"
388
388
  }