@askrjs/askr 0.0.61 → 0.0.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/actions/index.d.ts +1 -1
  2. package/dist/benchmark.js +4 -4
  3. package/dist/boot/index.d.ts +6 -2
  4. package/dist/boot/index.js +1 -1
  5. package/dist/{boot-DmVZR_IA.js → boot-BwqMApN4.js} +37 -12
  6. package/dist/components/index.d.ts +2 -2
  7. package/dist/control/index.d.ts +1 -1
  8. package/dist/{control-Bf4Wkdvv.d.ts → control-B5xu8v4m.d.ts} +1 -1
  9. package/dist/{control-D-9LKE3W.d.ts → control-CMzFPMjr.d.ts} +4 -1
  10. package/dist/csp-nonce-C-8E85El.js +33 -0
  11. package/dist/{deferred-BeNnjR4r.js → deferred-vBQJwHl5.js} +1 -1
  12. package/dist/foundations/icon/index.d.ts +1 -1
  13. package/dist/foundations/index.d.ts +2 -2
  14. package/dist/foundations/state/index.d.ts +1 -1
  15. package/dist/foundations/structures/index.d.ts +2 -2
  16. package/dist/{index-YLt-Qg_P.d.ts → index-Bjm0__Rr.d.ts} +2 -2
  17. package/dist/{index-DdkXZQEM.d.ts → index-Byqjltu2.d.ts} +2 -2
  18. package/dist/{index-XB38_9B8.d.ts → index-NKPpdRh9.d.ts} +6 -2
  19. package/dist/{index-BRjBZbDy.d.ts → index-PgRn5wmg.d.ts} +2 -2
  20. package/dist/index.d.ts +6 -6
  21. package/dist/index.js +3 -2
  22. package/dist/{jsx-CP0gmYwJ.d.ts → jsx-Dvr2SGRG.d.ts} +5 -0
  23. package/dist/jsx-dev-runtime.d.ts +2 -2
  24. package/dist/{jsx-runtime-92bV2hSa.d.ts → jsx-runtime-iTU73uwP.d.ts} +2 -2
  25. package/dist/jsx-runtime.d.ts +2 -2
  26. package/dist/{navigate-DLi79IZr.js → navigate-CaFA0DdW.js} +62 -8
  27. package/dist/{renderer-DhojfVg4.js → renderer-aUD-acDe.js} +9 -7
  28. package/dist/router/index.d.ts +3 -3
  29. package/dist/router/index.js +2 -2
  30. package/dist/{router-DGbBBIB-.d.ts → router-Dz7ZoLja.d.ts} +2 -2
  31. package/dist/ssg/index.d.ts +2 -2
  32. package/dist/ssg/index.js +2 -2
  33. package/dist/ssr/index.d.ts +9 -3
  34. package/dist/ssr/index.js +1 -1
  35. package/dist/{ssr-CbU-1UHm.js → ssr-CAYo-kNy.js} +49 -21
  36. package/dist/testing/index.d.ts +1 -1
  37. package/dist/{types-BujHn5pL.d.ts → types-4k3RFEaC.d.ts} +1 -1
  38. package/dist/{verify-hydration-BaWDqe5H.js → verify-hydration-DfsBcGSf.js} +1 -1
  39. package/package.json +1 -1
  40. package/dist/router-internal-BC0w1_xk.js +0 -4
@@ -1,2 +1,2 @@
1
- import { a as action, i as ActionValidationError, n as ActionForm, o as defineAction, r as ActionStatus, t as ActionDescriptor } from "../index-YLt-Qg_P.js";
1
+ import { a as action, i as ActionValidationError, n as ActionForm, o as defineAction, r as ActionStatus, t as ActionDescriptor } from "../index-Bjm0__Rr.js";
2
2
  export { ActionDescriptor, ActionForm, ActionStatus, ActionValidationError, action, defineAction };
package/dist/benchmark.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { r as flushRuntimeScheduler } from "./access-ePqdQqkV.js";
2
- import { t as installRendererBridge } from "./renderer-DhojfVg4.js";
2
+ import { t as installRendererBridge } from "./renderer-aUD-acDe.js";
3
3
  import { t as state } from "./state-Cc5HumQ0.js";
4
4
  import { t as selector } from "./selector-pApF_lGd.js";
5
5
  import { jsx, jsxs } from "./jsx-runtime.js";
6
6
  import { i as For } from "./control-KVP6LMEQ.js";
7
- import { t as createIsland } from "./boot-DmVZR_IA.js";
7
+ import { t as createIsland } from "./boot-BwqMApN4.js";
8
8
  //#region src/bench/components/benchmark-row.tsx
9
9
  function BenchmarkRow({ item, isSelected, onSelect, onRemove }) {
10
10
  return /* @__PURE__ */ jsxs("tr", {
@@ -63,8 +63,8 @@ function BenchmarkTable({ rows, isSelected, onSelect, onRemove }) {
63
63
  installRendererBridge();
64
64
  const benchmarkMetadata = {
65
65
  packageName: "@askrjs/askr",
66
- packageVersion: "0.0.61",
67
- buildLabel: "0.0.61-local"
66
+ packageVersion: "0.0.64",
67
+ buildLabel: "0.0.64-local"
68
68
  };
69
69
  function getBenchmarkMetadata() {
70
70
  return { ...benchmarkMetadata };
@@ -1,17 +1,19 @@
1
- import { s as ComponentFunction } from "../control-D-9LKE3W.js";
1
+ import { s as ComponentFunction } from "../control-CMzFPMjr.js";
2
2
  import { v as DataRuntime } from "../index-Bki2rqcr.js";
3
- import { P as RouteRegistry, m as RouteAuthOptions, p as Route, x as RouteManifest } from "../router-DGbBBIB-.js";
3
+ import { P as RouteRegistry, m as RouteAuthOptions, p as Route, x as RouteManifest } from "../router-Dz7ZoLja.js";
4
4
  import { d as ScrollRestorationOptions } from "../navigate-BVDCzOuB.js";
5
5
 
6
6
  //#region src/boot/types.d.ts
7
7
  type IslandConfig = {
8
8
  root: Element | string;
9
9
  component: ComponentFunction;
10
+ cspNonce?: string;
10
11
  cleanupStrict?: boolean;
11
12
  routes?: never;
12
13
  };
13
14
  type IslandsConfig = {
14
15
  islands: IslandConfig[];
16
+ cspNonce?: string;
15
17
  };
16
18
  type BootRouteSource = {
17
19
  registry: RouteRegistry;
@@ -28,6 +30,7 @@ type BootRouteSource = {
28
30
  };
29
31
  type SPAConfig = BootRouteSource & {
30
32
  root: Element | string;
33
+ cspNonce?: string;
31
34
  /**
32
35
  * Preferred: pass a route registry built via `createRouteRegistry(() => { ... })`.
33
36
  * ```ts
@@ -43,6 +46,7 @@ type SPAConfig = BootRouteSource & {
43
46
  };
44
47
  type HydrateSPAConfig = BootRouteSource & {
45
48
  root: Element | string;
49
+ cspNonce?: string;
46
50
  dataRuntime?: DataRuntime; /** Preferred route input - see `SPAConfig`. */
47
51
  auth?: RouteAuthOptions;
48
52
  scrollRestoration?: boolean | ScrollRestorationOptions;
@@ -1,2 +1,2 @@
1
- import { a as cleanupApp, i as hydrateSPA, n as createIslands, o as hasApp, r as createSPA, t as createIsland } from "../boot-DmVZR_IA.js";
1
+ import { a as cleanupApp, i as hydrateSPA, n as createIslands, o as hasApp, r as createSPA, t as createIsland } from "../boot-BwqMApN4.js";
2
2
  export { cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA };
@@ -2,15 +2,16 @@ import { b as isDevelopmentEnvironment, r as flushRuntimeScheduler, v as logger,
2
2
  import { n as Fragment, t as ELEMENT_TYPE } from "./jsx-CUpRxrLH.js";
3
3
  import { n as createComponentInstance, r as executeComponent } from "./component-internal-CbALfPGD.js";
4
4
  import { h as cleanupComponent, m as isPromiseLike } from "./component-lifecycle-DEMPihoZ.js";
5
- import { a as withIntrinsicHydrationAdoption, i as registerDeferredHydrationBoundary, n as activateHydrationBoundary$1, o as setStaticChildSlotsCacheEnabled, r as clearDeferredHydrationBoundaries, t as installRendererBridge } from "./renderer-DhojfVg4.js";
5
+ import { a as withIntrinsicHydrationAdoption, i as registerDeferredHydrationBoundary, n as activateHydrationBoundary$1, o as setStaticChildSlotsCacheEnabled, r as clearDeferredHydrationBoundaries, t as installRendererBridge } from "./renderer-aUD-acDe.js";
6
6
  import { _ as teardownNodeSubtree, d as removeAllListeners } from "./cleanup-B6KovDZZ.js";
7
- import { C as assertExecutionModel, S as route, a as resolveRouteMeta, c as registerAppInstance, d as clearRoutes, g as createAppRenderRuntime, h as setServerLocation, i as reconcileRouteMeta, l as unregisterAppInstance, s as configureScrollRestoration, t as initializeNavigation, u as _applyManifest } from "./navigate-DLi79IZr.js";
7
+ import { C as assertExecutionModel, S as route, a as resolveRouteMeta, c as registerAppInstance, d as clearRoutes, g as createAppRenderRuntime, h as setServerLocation, i as reconcileRouteMeta, l as unregisterAppInstance, s as configureScrollRestoration, t as initializeNavigation, u as _applyManifest } from "./navigate-CaFA0DdW.js";
8
8
  import { a as startHydrationRenderPhase, s as stopHydrationRenderPhase } from "./render-context-Clw3rFiO.js";
9
9
  import { a as disposeDefaultPortalScope, t as DefaultPortal } from "./portal-D2tPWNrC.js";
10
+ import { r as validateCspNonce, t as CspNonceScope } from "./csp-nonce-C-8E85El.js";
10
11
  import { i as getDefaultDataRuntime } from "./data-runtime-SJ1BSUvk.js";
11
12
  import { a as hydrateDataRuntime } from "./query-registry-CQIT4mXr.js";
12
13
  import { a as resolveRouteFromRoutes, d as _setActiveRouteAuthOptions, j as lockRouteRegistration, k as hasRegisteredRoutes } from "./route-matching-vJpvLVbX.js";
13
- import { _ as pageRenderEnvelope, d as hasRouteRenderData, f as resolveRouteRequest, l as getRouteRenderContext, o as reviveDeferredValue, u as getRouteRenderData, x as _preloadRouteHandler } from "./deferred-BeNnjR4r.js";
14
+ import { _ as pageRenderEnvelope, d as hasRouteRenderData, f as resolveRouteRequest, l as getRouteRenderContext, o as reviveDeferredValue, u as getRouteRenderData, x as _preloadRouteHandler } from "./deferred-vBQJwHl5.js";
14
15
  import "./ssr-CbQO5xd3.js";
15
16
  //#region src/boot/hydration.ts
16
17
  const DEFERRED_PAYLOAD = "__askr_deferred__";
@@ -259,6 +260,7 @@ function attachCleanupForRoot(rootElement, instance) {
259
260
  } catch {}
260
261
  }
261
262
  function mountOrUpdate(rootElement, componentFn, options) {
263
+ const nonce = validateCspNonce(options?.cspNonce);
262
264
  const wrappedFn = (props, ctx) => {
263
265
  const out = componentFn(props, ctx);
264
266
  if (isPromiseLike(out)) throw new Error("Async components are not supported. Components must return synchronously.");
@@ -268,11 +270,15 @@ function mountOrUpdate(rootElement, componentFn, options) {
268
270
  props: { __askrAutoDefaultPortal: true },
269
271
  key: "__default_portal"
270
272
  };
271
- return {
273
+ const root = {
272
274
  $$typeof: ELEMENT_TYPE,
273
275
  type: Fragment,
274
276
  props: { children: out === void 0 || out === null ? [portalVNode] : [out, portalVNode] }
275
277
  };
278
+ return nonce === void 0 ? root : CspNonceScope({
279
+ value: nonce,
280
+ children: root
281
+ });
276
282
  };
277
283
  Object.defineProperty(wrappedFn, "name", { value: componentFn.name || "Component" });
278
284
  const existingCleanup = rootElement[CLEANUP_SYMBOL];
@@ -298,6 +304,7 @@ function mountOrUpdate(rootElement, componentFn, options) {
298
304
  instance.isRoot = true;
299
305
  instance.portalScope = instance;
300
306
  instance._appRenderRuntime = options?.appRuntime;
307
+ instance._cspNonce = nonce;
301
308
  if (shouldResetHookState) {
302
309
  instance.stateValues = [];
303
310
  instance.hasPendingUpdate = false;
@@ -323,6 +330,7 @@ function mountOrUpdate(rootElement, componentFn, options) {
323
330
  instance._rootComponentFn = componentFn;
324
331
  instance.portalScope = instance;
325
332
  instance._appRenderRuntime = options?.appRuntime;
333
+ instance._cspNonce = nonce;
326
334
  if (options && typeof options.cleanupStrict === "boolean") instance.cleanupStrict = options.cleanupStrict;
327
335
  }
328
336
  attachCleanupForRoot(rootElement, instance);
@@ -440,11 +448,15 @@ function createIsland(config) {
440
448
  assertExecutionModel("islands");
441
449
  if (!config || typeof config !== "object") throw new Error("createIsland requires a config object");
442
450
  if (typeof config.component !== "function") throw new Error("createIsland: component must be a function");
451
+ validateCspNonce(config.cspNonce);
443
452
  const rootElement = resolveRootElement(config.root);
444
453
  if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
445
454
  if ("routes" in config) throw new Error("createIsland does not accept routes; use createSPA for routed apps");
446
455
  if (hasRegisteredRoutes()) throw new Error("Routes are not supported with islands. Use createSPA (client) or createSSR (server) instead.");
447
- mountOrUpdate(rootElement, config.component, { cleanupStrict: config.cleanupStrict });
456
+ mountOrUpdate(rootElement, config.component, {
457
+ cleanupStrict: config.cleanupStrict,
458
+ cspNonce: config.cspNonce
459
+ });
448
460
  }
449
461
  /**
450
462
  * createIslands: Enhances one or more existing DOM roots (no router).
@@ -453,8 +465,12 @@ function createIsland(config) {
453
465
  function createIslands(config) {
454
466
  assertExecutionModel("islands");
455
467
  if (!config || typeof config !== "object") throw new Error("createIslands requires a config object");
468
+ validateCspNonce(config.cspNonce);
456
469
  if (!Array.isArray(config.islands) || config.islands.length === 0) throw new Error("createIslands requires a non-empty islands array");
457
- for (const island of config.islands) createIsland(island);
470
+ for (const island of config.islands) createIsland({
471
+ ...island,
472
+ cspNonce: island.cspNonce ?? config.cspNonce
473
+ });
458
474
  }
459
475
  /**
460
476
  * createSPA: Initializes router and mounts the app with the provided route manifest or route table.
@@ -473,6 +489,7 @@ function createIslands(config) {
473
489
  async function createSPA(config) {
474
490
  assertExecutionModel("spa");
475
491
  if (!config || typeof config !== "object") throw new Error("createSPA requires a config object");
492
+ validateCspNonce(config.cspNonce);
476
493
  const manifest = config.manifest ?? config.registry?.manifest;
477
494
  const routeTable = config.routes ?? config.registry?.routes;
478
495
  const hasManifest = manifest != null && manifest.records.length > 0;
@@ -507,7 +524,8 @@ async function createSPA(config) {
507
524
  children: []
508
525
  }), {
509
526
  cleanupStrict: config.cleanupStrict,
510
- appRuntime
527
+ appRuntime,
528
+ cspNonce: config.cspNonce
511
529
  });
512
530
  await registerAppNavigation(rootElement, path, { ...appRouteSource });
513
531
  return;
@@ -518,7 +536,8 @@ async function createSPA(config) {
518
536
  children: []
519
537
  }), {
520
538
  cleanupStrict: config.cleanupStrict,
521
- appRuntime
539
+ appRuntime,
540
+ cspNonce: config.cspNonce
522
541
  });
523
542
  await registerAppNavigation(rootElement, path, { ...appRouteSource });
524
543
  return;
@@ -529,7 +548,8 @@ async function createSPA(config) {
529
548
  params: resolved.params
530
549
  }), {
531
550
  cleanupStrict: config.cleanupStrict,
532
- appRuntime
551
+ appRuntime,
552
+ cspNonce: config.cspNonce
533
553
  });
534
554
  await registerAppNavigation(rootElement, path, { ...appRouteSource });
535
555
  }
@@ -540,6 +560,7 @@ async function createSPA(config) {
540
560
  async function hydrateSPA(config) {
541
561
  assertExecutionModel("spa");
542
562
  if (!config || typeof config !== "object") throw new Error("hydrateSPA requires a config object");
563
+ validateCspNonce(config.cspNonce);
543
564
  const manifest = config.manifest ?? config.registry?.manifest;
544
565
  const routeTable = config.routes ?? config.registry?.routes;
545
566
  const hasManifest = manifest != null && manifest.records.length > 0;
@@ -586,7 +607,10 @@ async function hydrateSPA(config) {
586
607
  handler: resolved.handler,
587
608
  params: resolved.params
588
609
  };
589
- const mountHydratedRoot = (...args) => withIntrinsicHydrationAdoption(() => mountOrUpdate(...args));
610
+ const mountHydratedRoot = (...args) => withIntrinsicHydrationAdoption(() => mountOrUpdate(args[0], args[1], {
611
+ ...args[2],
612
+ cspNonce: config.cspNonce
613
+ }));
590
614
  if (shouldVerifyHydrationMarkup(config)) {
591
615
  const legacyRouteTable = hasManifest ? manifest.records.map((r) => ({
592
616
  ...r,
@@ -594,7 +618,7 @@ async function hydrateSPA(config) {
594
618
  handler: r.handler,
595
619
  namespace: r.options.namespace
596
620
  })) : routeTable;
597
- const { verifyHydrationSyncForUrl } = await import("./verify-hydration-BaWDqe5H.js");
621
+ const { verifyHydrationSyncForUrl } = await import("./verify-hydration-DfsBcGSf.js");
598
622
  if (!verifyHydrationSyncForUrl({
599
623
  root: rootElement,
600
624
  url: currentUrl,
@@ -603,7 +627,8 @@ async function hydrateSPA(config) {
603
627
  options: {
604
628
  data: hydrationRenderDataForApp?.resources,
605
629
  dataRuntime: config.dataRuntime ?? getDefaultDataRuntime(),
606
- envelope: hydrationRenderDataForApp ?? void 0
630
+ envelope: hydrationRenderDataForApp ?? void 0,
631
+ cspNonce: config.cspNonce
607
632
  }
608
633
  })) throw new Error("[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output.");
609
634
  }
@@ -1,5 +1,5 @@
1
- import { l as VNode } from "../control-D-9LKE3W.js";
2
- import { r as JSXElement, s as Props } from "../jsx-CP0gmYwJ.js";
1
+ import { l as VNode } from "../control-CMzFPMjr.js";
2
+ import { r as JSXElement, s as Props } from "../jsx-Dvr2SGRG.js";
3
3
 
4
4
  //#region src/common/error-boundary.d.ts
5
5
  type ErrorBoundaryContent = VNode | readonly VNode[];
@@ -1,2 +1,2 @@
1
- import { a as Show, c as ForProps, i as MatchProps, n as CaseProps, o as ShowProps, r as Match, s as For, t as Case } from "../index-DdkXZQEM.js";
1
+ import { a as Show, c as ForProps, i as MatchProps, n as CaseProps, o as ShowProps, r as Match, s as For, t as Case } from "../index-Byqjltu2.js";
2
2
  export { Case, type CaseProps, For, type ForProps, Match, type MatchProps, Show, type ShowProps };
@@ -1,4 +1,4 @@
1
- import { s as Props } from "./jsx-CP0gmYwJ.js";
1
+ import { s as Props } from "./jsx-Dvr2SGRG.js";
2
2
 
3
3
  //#region src/common/control.d.ts
4
4
  declare const EAGER_CONTROL_PRIMITIVE: unique symbol;
@@ -1,4 +1,4 @@
1
- import { i as JSXElementType, r as JSXElement, s as Props } from "./jsx-CP0gmYwJ.js";
1
+ import { i as JSXElementType, r as JSXElement, s as Props } from "./jsx-Dvr2SGRG.js";
2
2
 
3
3
  //#region src/runtime/state.d.ts
4
4
  /**
@@ -70,6 +70,7 @@ interface DocumentRenderContext {
70
70
  data?: SSRData;
71
71
  seed: number;
72
72
  route: DocumentRenderRoute;
73
+ cspNonce?: string;
73
74
  }
74
75
  interface DocumentRenderArgs {
75
76
  appHtml: string;
@@ -170,6 +171,8 @@ interface ComponentInstance {
170
171
  _rootComponentFn?: ComponentFunction;
171
172
  /** @internal Browser-owned hydration and route state for this app root. */
172
173
  _appRenderRuntime?: AppRenderRuntime;
174
+ /** @internal CSP nonce retained across browser route navigation. */
175
+ _cspNonce?: string;
173
176
  _vnodeOwner?: object;
174
177
  _vnodeParent?: ComponentInstance | null;
175
178
  _vnodeParentGeneration?: object;
@@ -0,0 +1,33 @@
1
+ import { l as defineScope, m as readScope } from "./component-internal-CbALfPGD.js";
2
+ //#region src/common/router-internal.ts
3
+ const ROUTE_ROOT_COMPONENT = Symbol.for("askr.route-root-component");
4
+ //#endregion
5
+ //#region src/csp-nonce.ts
6
+ const CspNonceScope = defineScope(void 0);
7
+ function cspNonce() {
8
+ try {
9
+ return readScope(CspNonceScope);
10
+ } catch (error) {
11
+ if (error instanceof Error && error.message.startsWith("readScope() can only be called during component render")) return;
12
+ throw error;
13
+ }
14
+ }
15
+ function validateCspNonce(value) {
16
+ if (value === void 0) return void 0;
17
+ const invalid = () => {
18
+ throw new TypeError("CSP nonce must be valid base64 or base64url encoding at least 16 bytes.");
19
+ };
20
+ if (value.length === 0 || !/^[A-Za-z0-9+/_-]+={0,2}$/.test(value) || value.length % 4 === 1 || /=/.test(value.slice(0, -2))) invalid();
21
+ const unpadded = value.replace(/-/g, "+").replace(/_/g, "/").replace(/=+$/, "");
22
+ const padded = unpadded.padEnd(Math.ceil(unpadded.length / 4) * 4, "=");
23
+ let decoded = "";
24
+ try {
25
+ decoded = atob(padded);
26
+ } catch {
27
+ invalid();
28
+ }
29
+ if (decoded.length < 16) invalid();
30
+ return value;
31
+ }
32
+ //#endregion
33
+ export { ROUTE_ROOT_COMPONENT as i, cspNonce as n, validateCspNonce as r, CspNonceScope as t };
@@ -4,7 +4,7 @@ import { d as getCurrentAppRenderRuntime } from "./component-scope-CC3cojX9.js";
4
4
  import { m as isPromiseLike } from "./component-lifecycle-DEMPihoZ.js";
5
5
  import { n as getActiveRenderContext, r as getCurrentRenderData } from "./render-context-Clw3rFiO.js";
6
6
  import { t as resource } from "./resource-operation-Dz2Nxi1q.js";
7
- import { t as ROUTE_ROOT_COMPONENT } from "./router-internal-BC0w1_xk.js";
7
+ import { i as ROUTE_ROOT_COMPONENT } from "./csp-nonce-C-8E85El.js";
8
8
  import { c as withTelemetry, t as createQueryPrefetchContext } from "./query-registry-CQIT4mXr.js";
9
9
  import { E as getRouteRecords, h as getActiveRouteAuthOptions, i as getMatchingRouteRecord, o as buildRouteContext, s as buildRouteContextBase } from "./route-matching-vJpvLVbX.js";
10
10
  //#region src/router/lazy.ts
@@ -1,4 +1,4 @@
1
- import { r as JSXElement, s as Props } from "../../jsx-CP0gmYwJ.js";
1
+ import { r as JSXElement, s as Props } from "../../jsx-Dvr2SGRG.js";
2
2
  import { t as Ref } from "../../compose-ref-Cizq72-x.js";
3
3
 
4
4
  //#region src/foundations/icon/icon.types.d.ts
@@ -1,3 +1,3 @@
1
- import { r as JSXElement } from "../jsx-CP0gmYwJ.js";
2
- import { _ as definePortal, c as Presence, d as SlotProps, f as LayoutComponent, g as PortalProps, h as Portal, l as PresenceProps, m as DefaultPortal, p as layout, u as Slot } from "../index-BRjBZbDy.js";
1
+ import { r as JSXElement } from "../jsx-Dvr2SGRG.js";
2
+ import { _ as definePortal, c as Presence, d as SlotProps, f as LayoutComponent, g as PortalProps, h as Portal, l as PresenceProps, m as DefaultPortal, p as layout, u as Slot } from "../index-PgRn5wmg.js";
3
3
  export { DefaultPortal, type JSXElement, type LayoutComponent, Portal, type PortalProps, Presence, type PresenceProps, Slot, type SlotProps, definePortal, layout };
@@ -1,4 +1,4 @@
1
- import { m as State } from "../../control-D-9LKE3W.js";
1
+ import { m as State } from "../../control-CMzFPMjr.js";
2
2
 
3
3
  //#region src/foundations/state/controllable.d.ts
4
4
  declare function isControlled<T>(value: T | undefined): value is T;
@@ -1,3 +1,3 @@
1
- import { r as JSXElement } from "../../jsx-CP0gmYwJ.js";
2
- import { _ as definePortal, a as Collection, c as Presence, d as SlotProps, f as LayoutComponent, g as PortalProps, h as Portal, i as createLayer, l as PresenceProps, m as DefaultPortal, n as LayerManager, o as CollectionItem, p as layout, r as LayerOptions, s as createCollection, t as Layer, u as Slot } from "../../index-BRjBZbDy.js";
1
+ import { r as JSXElement } from "../../jsx-Dvr2SGRG.js";
2
+ import { _ as definePortal, a as Collection, c as Presence, d as SlotProps, f as LayoutComponent, g as PortalProps, h as Portal, i as createLayer, l as PresenceProps, m as DefaultPortal, n as LayerManager, o as CollectionItem, p as layout, r as LayerOptions, s as createCollection, t as Layer, u as Slot } from "../../index-PgRn5wmg.js";
3
3
  export { type Collection, type CollectionItem, DefaultPortal, type JSXElement, type Layer, type LayerManager, type LayerOptions, type LayoutComponent, Portal, type PortalProps, Presence, type PresenceProps, Slot, type SlotProps, createCollection, createLayer, definePortal, layout };
@@ -1,5 +1,5 @@
1
- import { c as RenderableChild, g as StateTuple } from "./control-D-9LKE3W.js";
2
- import { r as JSXElement } from "./jsx-CP0gmYwJ.js";
1
+ import { c as RenderableChild, g as StateTuple } from "./control-CMzFPMjr.js";
2
+ import { r as JSXElement } from "./jsx-Dvr2SGRG.js";
3
3
  import { ObjectSchema } from "@askrjs/schema";
4
4
 
5
5
  //#region src/actions/index.d.ts
@@ -1,5 +1,5 @@
1
- import { c as RenderableChild, l as VNode, t as ForEachSource } from "./control-D-9LKE3W.js";
2
- import { r as JSXElement } from "./jsx-CP0gmYwJ.js";
1
+ import { c as RenderableChild, l as VNode, t as ForEachSource } from "./control-CMzFPMjr.js";
2
+ import { r as JSXElement } from "./jsx-Dvr2SGRG.js";
3
3
 
4
4
  //#region src/control/shared.d.ts
5
5
  type BoundaryChild = RenderableChild;
@@ -1,4 +1,4 @@
1
- import { n as ReadableSource, r as ComponentInstance } from "./control-D-9LKE3W.js";
1
+ import { i as Scope, n as ReadableSource, r as ComponentInstance } from "./control-CMzFPMjr.js";
2
2
  import { t as Scheduler } from "./scheduler-CmLO4Dfm.js";
3
3
  //#region src/runtime/runtime.d.ts
4
4
  interface RuntimeKeyedReorderDecision {
@@ -62,4 +62,8 @@ type SelectorEquals<T> = {
62
62
  }['bivarianceHack'];
63
63
  declare function selector<T>(source: () => T, equals?: SelectorEquals<T>): Selector<T>;
64
64
  //#endregion
65
- export { AskrRuntime as a, RuntimeRendererHost as c, derive as i, createRuntime as l, selector as n, AskrRuntimeOptions as o, Derived as r, RuntimeKeyedReorderDecision as s, Selector as t, getDefaultRuntime as u };
65
+ //#region src/csp-nonce.d.ts
66
+ declare const CspNonceScope: Scope<string | undefined>;
67
+ declare function cspNonce(): string | undefined;
68
+ //#endregion
69
+ export { Derived as a, AskrRuntimeOptions as c, createRuntime as d, getDefaultRuntime as f, selector as i, RuntimeKeyedReorderDecision as l, cspNonce as n, derive as o, Selector as r, AskrRuntime as s, CspNonceScope as t, RuntimeRendererHost as u };
@@ -1,5 +1,5 @@
1
- import { c as RenderableChild } from "./control-D-9LKE3W.js";
2
- import { r as JSXElement } from "./jsx-CP0gmYwJ.js";
1
+ import { c as RenderableChild } from "./control-CMzFPMjr.js";
2
+ import { r as JSXElement } from "./jsx-Dvr2SGRG.js";
3
3
  //#region src/runtime/portal.d.ts
4
4
  interface Portal<T extends RenderableChild = RenderableChild> {
5
5
  (): unknown;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { _ as state, a as defineScope, g as StateTuple, h as StateSetter, i as Scope, m as State, o as readScope } from "./control-D-9LKE3W.js";
2
- import { s as Props, t as Fragment } from "./jsx-CP0gmYwJ.js";
1
+ import { _ as state, a as defineScope, g as StateTuple, h as StateSetter, i as Scope, m as State, o as readScope } from "./control-CMzFPMjr.js";
2
+ import { s as Props, t as Fragment } from "./jsx-Dvr2SGRG.js";
3
3
  import { t as getSignal } from "./component-scope-CvPba6O6.js";
4
- import { a as AskrRuntime, c as RuntimeRendererHost, i as derive, l as createRuntime, n as selector, o as AskrRuntimeOptions, r as Derived, s as RuntimeKeyedReorderDecision, t as Selector, u as getDefaultRuntime } from "./index-XB38_9B8.js";
5
- import { a as Show, c as ForProps, i as MatchProps, n as CaseProps, o as ShowProps, r as Match, s as For, t as Case } from "./index-DdkXZQEM.js";
6
- import { i as jsxs, n as jsx } from "./jsx-runtime-92bV2hSa.js";
4
+ import { a as Derived, c as AskrRuntimeOptions, d as createRuntime, f as getDefaultRuntime, i as selector, l as RuntimeKeyedReorderDecision, n as cspNonce, o as derive, r as Selector, s as AskrRuntime, t as CspNonceScope, u as RuntimeRendererHost } from "./index-NKPpdRh9.js";
5
+ import { a as Show, c as ForProps, i as MatchProps, n as CaseProps, o as ShowProps, r as Match, s as For, t as Case } from "./index-Byqjltu2.js";
6
+ import { i as jsxs, n as jsx } from "./jsx-runtime-iTU73uwP.js";
7
7
  import { A as ServerQueryHandler, D as QueryPrefetchContext, T as QueryDefinition, a as defineServerQueries, c as prefetchQuery, g as createQuery, i as defineQuery, l as serveQuery, o as dehydrateDataRuntime, s as hydrateDataRuntime, v as DataRuntime } from "./index-Bki2rqcr.js";
8
- export { AskrRuntime, type AskrRuntimeOptions, Case, type CaseProps, type DataRuntime, type Derived, For, type ForProps, Fragment, Match, type MatchProps, type Props, type QueryDefinition, type QueryPrefetchContext, type RuntimeKeyedReorderDecision, type RuntimeRendererHost, type Scope, type Selector, type ServerQueryHandler, Show, type ShowProps, type State, type StateSetter, type StateTuple, createQuery, createRuntime, defineQuery, defineScope, defineServerQueries, dehydrateDataRuntime, derive, getDefaultRuntime, getSignal, hydrateDataRuntime, jsx, jsxs, prefetchQuery, readScope, selector, serveQuery, state };
8
+ export { AskrRuntime, type AskrRuntimeOptions, Case, type CaseProps, CspNonceScope, type DataRuntime, type Derived, For, type ForProps, Fragment, Match, type MatchProps, type Props, type QueryDefinition, type QueryPrefetchContext, type RuntimeKeyedReorderDecision, type RuntimeRendererHost, type Scope, type Selector, type ServerQueryHandler, Show, type ShowProps, type State, type StateSetter, type StateTuple, createQuery, createRuntime, cspNonce, defineQuery, defineScope, defineServerQueries, dehydrateDataRuntime, derive, getDefaultRuntime, getSignal, hydrateDataRuntime, jsx, jsxs, prefetchQuery, readScope, selector, serveQuery, state };
package/dist/index.js CHANGED
@@ -4,10 +4,11 @@ import { n as Fragment } from "./jsx-CUpRxrLH.js";
4
4
  import { l as defineScope, m as readScope } from "./component-internal-CbALfPGD.js";
5
5
  import { g as getSignal, i as claimHookIndex, p as getCurrentInstance } from "./component-scope-CC3cojX9.js";
6
6
  import { n as isSnapshotSource } from "./snapshot-source-BB42xgwb.js";
7
- import { t as installRendererBridge } from "./renderer-DhojfVg4.js";
7
+ import { t as installRendererBridge } from "./renderer-aUD-acDe.js";
8
8
  import { t as state } from "./state-Cc5HumQ0.js";
9
9
  import { t as selector } from "./selector-pApF_lGd.js";
10
10
  import { jsx, jsxs } from "./jsx-runtime.js";
11
+ import { n as cspNonce, t as CspNonceScope } from "./csp-nonce-C-8E85El.js";
11
12
  import { i as For, n as Match, r as Show, t as Case } from "./control-KVP6LMEQ.js";
12
13
  import { t as createQuery } from "./data-DvYo_dHd.js";
13
14
  import { a as hydrateDataRuntime, i as dehydrateDataRuntime, n as defineQuery, o as prefetchQuery, r as defineServerQueries, s as serveQuery } from "./query-registry-CQIT4mXr.js";
@@ -156,4 +157,4 @@ function derive(source, map) {
156
157
  */
157
158
  installRendererBridge();
158
159
  //#endregion
159
- export { AskrRuntime, Case, For, Fragment, Match, Show, createQuery, createRuntime, defineQuery, defineScope, defineServerQueries, dehydrateDataRuntime, derive, getDefaultRuntime, getSignal, hydrateDataRuntime, jsx, jsxs, prefetchQuery, readScope, selector, serveQuery, state };
160
+ export { AskrRuntime, Case, CspNonceScope, For, Fragment, Match, Show, createQuery, createRuntime, cspNonce, defineQuery, defineScope, defineServerQueries, dehydrateDataRuntime, derive, getDefaultRuntime, getSignal, hydrateDataRuntime, jsx, jsxs, prefetchQuery, readScope, selector, serveQuery, state };
@@ -73,6 +73,11 @@ interface IntrinsicEventProps {
73
73
  interface IntrinsicProps extends IntrinsicEventProps {
74
74
  key?: string | number | symbol;
75
75
  children?: unknown;
76
+ /**
77
+ * Leaves descendant DOM ownership to an imperative widget after mount.
78
+ * Askr will continue updating the host element's props, events, and ref.
79
+ */
80
+ imperativeChildren?: boolean;
76
81
  class?: ReactiveProp<IntrinsicClassValue>;
77
82
  className?: ReactiveProp<IntrinsicClassValue>;
78
83
  style?: ReactiveProp<IntrinsicStyleValue>;
@@ -1,5 +1,5 @@
1
- import { a as IntrinsicFallbackProps, i as JSXElementType, n as JSXComponent, o as KnownIntrinsicElementProps, r as JSXElement, s as Props, t as Fragment } from "./jsx-CP0gmYwJ.js";
2
- import { t as EagerControlPrimitive } from "./control-Bf4Wkdvv.js";
1
+ import { a as IntrinsicFallbackProps, i as JSXElementType, n as JSXComponent, o as KnownIntrinsicElementProps, r as JSXElement, s as Props, t as Fragment } from "./jsx-Dvr2SGRG.js";
2
+ import { t as EagerControlPrimitive } from "./control-B5xu8v4m.js";
3
3
  //#region src/jsx/jsx-dev-runtime.d.ts
4
4
  declare namespace JSX {
5
5
  interface Element extends JSXElement {
@@ -1,5 +1,5 @@
1
- import { a as IntrinsicFallbackProps, o as KnownIntrinsicElementProps, r as JSXElement, s as Props } from "./jsx-CP0gmYwJ.js";
2
- import { t as EagerControlPrimitive } from "./control-Bf4Wkdvv.js";
1
+ import { a as IntrinsicFallbackProps, o as KnownIntrinsicElementProps, r as JSXElement, s as Props } from "./jsx-Dvr2SGRG.js";
2
+ import { t as EagerControlPrimitive } from "./control-B5xu8v4m.js";
3
3
  //#region src/jsx/jsx-runtime.d.ts
4
4
  declare namespace JSX {
5
5
  interface Element extends JSXElement {
@@ -1,3 +1,3 @@
1
- import { i as JSXElementType, n as JSXComponent, r as JSXElement, t as Fragment } from "./jsx-CP0gmYwJ.js";
2
- import { i as jsxs, n as jsx, r as jsxDEV, t as JSX } from "./jsx-runtime-92bV2hSa.js";
1
+ import { i as JSXElementType, n as JSXComponent, r as JSXElement, t as Fragment } from "./jsx-Dvr2SGRG.js";
2
+ import { i as jsxs, n as jsx, r as jsxDEV, t as JSX } from "./jsx-runtime-iTU73uwP.js";
3
3
  export { Fragment, JSX, type JSXComponent, type JSXElement, type JSXElementType, jsx, jsxDEV, jsxs };
@@ -8,8 +8,9 @@ import { _ as teardownNodeSubtree } from "./cleanup-B6KovDZZ.js";
8
8
  import { n as getActiveRenderContext } from "./render-context-Clw3rFiO.js";
9
9
  import { n as syncRouteActivitySnapshot } from "./route-activity-CNJfpwx-.js";
10
10
  import { r as clearDefaultPortalForInstance, t as DefaultPortal } from "./portal-D2tPWNrC.js";
11
+ import { t as CspNonceScope } from "./csp-nonce-C-8E85El.js";
11
12
  import { A as insertRecordSorted, C as getCurrentPathPrefix, D as getRoutes, E as getRouteRecords, F as snapshotRouteState, I as computeRank, L as normalizeRouteSegmentName, M as pushRegistrationScope, N as restoreRouteState, O as hasActivePageScope, P as setDefaultRouteAuthOptions, R as parseSegments, S as getCurrentPageScope, T as getDefaultRouteAuthOptions, _ as getCurrentInheritedAuthRequirements, a as resolveRouteFromRoutes, b as getCurrentLayoutChain, c as deepFreeze, f as addRouteToStores, g as getActiveRoutes, j as lockRouteRegistration, l as makeQuery, m as clearRouteState, n as computeMatchesFromRoutes, p as assertRouteRegistrationUnlocked, r as computeRouteActivityMatches, u as parseLocation, v as getCurrentInheritedMeta, w as getCurrentScopeKind, x as getCurrentPageChain, y as getCurrentInheritedPolicies } from "./route-matching-vJpvLVbX.js";
12
- import { d as hasRouteRenderData, f as resolveRouteRequest, l as getRouteRenderContext, u as getRouteRenderData, x as _preloadRouteHandler, y as createRouteHandler } from "./deferred-BeNnjR4r.js";
13
+ import { d as hasRouteRenderData, f as resolveRouteRequest, l as getRouteRenderContext, u as getRouteRenderData, x as _preloadRouteHandler, y as createRouteHandler } from "./deferred-vBQJwHl5.js";
13
14
  import { allOf } from "@askrjs/auth";
14
15
  //#region src/runtime/execution-model.ts
15
16
  const EXECUTION_MODEL_KEY = Symbol.for("__ASKR_EXECUTION_MODEL__");
@@ -589,12 +590,61 @@ async function resolveRouteMeta(record, context) {
589
590
  /** Replace only Askr-owned head nodes after a successful client navigation. */
590
591
  function reconcileRouteMeta(meta, target = document) {
591
592
  for (const node of Array.from(target.head.querySelectorAll("[data-askr-head]"))) node.remove();
592
- const template = target.createElement("template");
593
- template.innerHTML = serializeRouteMeta(meta);
594
- target.head.append(template.content);
593
+ const own = (element) => {
594
+ element.setAttribute("data-askr-head", "");
595
+ return element;
596
+ };
597
+ const appendMeta = (attribute, name, content) => {
598
+ const element = own(target.createElement("meta"));
599
+ element.setAttribute(attribute, name);
600
+ element.setAttribute("content", content);
601
+ target.head.append(element);
602
+ };
603
+ if (meta.title !== void 0) {
604
+ const element = own(target.createElement("title"));
605
+ element.textContent = meta.title;
606
+ target.head.append(element);
607
+ }
608
+ if (meta.description !== void 0) appendMeta("name", "description", meta.description);
609
+ if (meta.canonical !== void 0) {
610
+ const element = own(target.createElement("link"));
611
+ element.setAttribute("rel", "canonical");
612
+ element.setAttribute("href", meta.canonical);
613
+ target.head.append(element);
614
+ }
615
+ if (meta.robots !== void 0) appendMeta("name", "robots", meta.robots);
616
+ for (const [property, content] of Object.entries(meta.openGraph ?? {})) appendMeta("property", property.startsWith("og:") ? property : `og:${property}`, content);
617
+ for (const link of meta.links ?? []) {
618
+ const element = own(target.createElement("link"));
619
+ for (const [name, value] of Object.entries(link)) if (LINK_ATTRIBUTES.has(name.toLowerCase())) element.setAttribute(name.toLowerCase(), value);
620
+ target.head.append(element);
621
+ }
622
+ if (meta.jsonLd !== void 0) {
623
+ const values = Array.isArray(meta.jsonLd) ? meta.jsonLd : [meta.jsonLd];
624
+ for (const value of values) {
625
+ const element = own(target.createElement("script"));
626
+ element.setAttribute("type", "application/ld+json");
627
+ element.textContent = JSON.stringify(value);
628
+ target.head.append(element);
629
+ }
630
+ }
595
631
  if (meta.html?.lang) target.documentElement.setAttribute("lang", meta.html.lang);
596
632
  if (meta.html?.dir) target.documentElement.setAttribute("dir", meta.html.dir);
597
633
  }
634
+ const LINK_ATTRIBUTES = /* @__PURE__ */ new Set([
635
+ "rel",
636
+ "href",
637
+ "as",
638
+ "crossorigin",
639
+ "fetchpriority",
640
+ "hreflang",
641
+ "imagesizes",
642
+ "imagesrcset",
643
+ "media",
644
+ "referrerpolicy",
645
+ "sizes",
646
+ "type"
647
+ ]);
598
648
  function escapeAttribute(value) {
599
649
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
600
650
  }
@@ -605,7 +655,7 @@ function ownedAttribute() {
605
655
  return " data-askr-head=\"\"";
606
656
  }
607
657
  function serializeLink(link) {
608
- const entries = Object.entries(link).filter(([name]) => /^[a-zA-Z][a-zA-Z0-9:_-]*$/.test(name)).sort(([left], [right]) => {
658
+ const entries = Object.entries(link).map(([name, value]) => [name.toLowerCase(), value]).filter(([name]) => LINK_ATTRIBUTES.has(name)).sort(([left], [right]) => {
609
659
  const order = (name) => name === "rel" ? 0 : name === "href" ? 1 : 2;
610
660
  return order(left) - order(right) || left.localeCompare(right);
611
661
  });
@@ -706,7 +756,7 @@ function createDeniedResolvedRoute(status) {
706
756
  function bindResolvedRouteHandler(resolved) {
707
757
  return () => resolved.handler(resolved.params);
708
758
  }
709
- function wrapRootRouteHandler(componentFn) {
759
+ function wrapRootRouteHandler(componentFn, cspNonce) {
710
760
  const wrappedFn = (props, ctx) => {
711
761
  const out = componentFn(props, ctx);
712
762
  if (isPromiseLike(out)) throw new Error("Async components are not supported. Components must return synchronously.");
@@ -716,11 +766,15 @@ function wrapRootRouteHandler(componentFn) {
716
766
  props: { __askrAutoDefaultPortal: true },
717
767
  key: "__default_portal"
718
768
  };
719
- return {
769
+ const root = {
720
770
  $$typeof: ELEMENT_TYPE,
721
771
  type: Fragment,
722
772
  props: { children: out === void 0 || out === null ? [portalVNode] : [out, portalVNode] }
723
773
  };
774
+ return cspNonce === void 0 ? root : CspNonceScope({
775
+ value: cspNonce,
776
+ children: root
777
+ });
724
778
  };
725
779
  Object.defineProperty(wrappedFn, "name", { value: componentFn.name || "Component" });
726
780
  return wrappedFn;
@@ -957,7 +1011,7 @@ function cleanupDeferredRouteInstance(deferred) {
957
1011
  function remountResolvedRoute(instance, resolved, pathname, href, existingSnapshot) {
958
1012
  const deferredCleanup = existingSnapshot ?? captureDeferredRouteCleanup(instance);
959
1013
  clearDefaultPortalForInstance(instance);
960
- instance.fn = wrapRootRouteHandler(bindResolvedRouteHandler(resolved));
1014
+ instance.fn = wrapRootRouteHandler(bindResolvedRouteHandler(resolved), instance._cspNonce);
961
1015
  instance.props = {};
962
1016
  instance._ownershipGeneration = {};
963
1017
  instance.stateValues = [];
@@ -10,7 +10,7 @@ import { _ as createChildScope, a as registerForStateTransaction, c as captureFo
10
10
  import { n as createOwnedFineGrainedEffect, r as markFineGrainedEffectsDirtySource, t as createFineGrainedEffect } from "./effect-D_4zf_wy.js";
11
11
  import { C as getDelegatedHandlersForElement, D as updateDelegatedListener, E as removeDelegatedListener, S as getDelegatedHandlerForElement, T as isEventDelegationEnabled, _ as teardownNodeSubtree, a as elementReactivePropsCleanup, b as addFreshDelegatedListener, c as forEachElementReactivePropCleanup, d as removeAllListeners, f as removeElementReactiveProps, g as setFreshElementReactivePropCleanup, h as setDirectElementReactivePropCleanup, i as elementListeners, l as getElementReactivePropCleanupSize, m as replaceElementRefBookkeeping, n as cleanupInstanceIfPresent, o as elementRefs, p as removeElementRef, r as cleanupInstancesUnder, s as forEachDescendantNode, t as REACTIVE_CHILDREN_KEY, u as getElementReactivePropsCleanupMap, v as updateElementRef, w as isDelegatedEvent, x as clearDelegatedHandlersForElement, y as addDelegatedListener } from "./cleanup-B6KovDZZ.js";
12
12
  import { t as getPublicAttributeName } from "./attr-names-CjhzmHOn.js";
13
- import { t as ROUTE_ROOT_COMPONENT } from "./router-internal-BC0w1_xk.js";
13
+ import { i as ROUTE_ROOT_COMPONENT } from "./csp-nonce-C-8E85El.js";
14
14
  //#region src/runtime/error-boundary.ts
15
15
  function createBoundaryReset(instance) {
16
16
  return () => {
@@ -155,7 +155,7 @@ function createMutableWrappedHandler(handler, flushAfter = false) {
155
155
  }
156
156
  /** Props that should be skipped during attribute processing */
157
157
  function isSkippedProp(key) {
158
- return key === "children" || key === "key" || key === "ref";
158
+ return key === "children" || key === "imperativeChildren" || key === "key" || key === "ref";
159
159
  }
160
160
  /** Check if prop should be ignored for prop-change detection */
161
161
  function isIgnoredForPropChanges(key) {
@@ -3704,12 +3704,12 @@ function processFragmentChildren(target, childArray, cleanupRangeNode) {
3704
3704
  }
3705
3705
  function applyPropsToElement(el, props) {
3706
3706
  for (const [key, value] of Object.entries(props)) {
3707
- if (key === "children" || key === "key") continue;
3708
- if (value === void 0 || value === null || value === false) continue;
3709
3707
  if (key === "ref") {
3710
3708
  updateElementRef(el, value);
3711
3709
  continue;
3712
3710
  }
3711
+ if (isSkippedProp(key)) continue;
3712
+ if (value === void 0 || value === null || value === false) continue;
3713
3713
  const eventProp = parseEventProp(key);
3714
3714
  if (eventProp) {
3715
3715
  const { eventName, capture } = eventProp;
@@ -6061,6 +6061,7 @@ function applyElementUpdateFromVnode(el, vnode, updateChildren, forceChildrenUpd
6061
6061
  if (!_isDOMElement(vnode)) return;
6062
6062
  const props = vnode.props || {};
6063
6063
  const domVNode = vnode;
6064
+ const shouldUpdateChildren = updateChildren && props.imperativeChildren !== true;
6064
6065
  if (isHydrationSkipped(el)) {
6065
6066
  rememberDeferredHydrationVNode(el, vnode, getCurrentInstance(), getCurrentInstance()?.ownerFrame ?? null);
6066
6067
  clearHydrationDeferredSubtree(el);
@@ -6070,7 +6071,7 @@ function applyElementUpdateFromVnode(el, vnode, updateChildren, forceChildrenUpd
6070
6071
  updateElementRef(el, props.ref);
6071
6072
  if (!hasTrackedElementPropBindings(el)) {
6072
6073
  if (!forceChildrenUpdate && hasMatchingStaticProps(el, props, vnode.type)) {
6073
- if (updateChildren) {
6074
+ if (shouldUpdateChildren) {
6074
6075
  const children = props.children ?? vnode.children;
6075
6076
  if (!forceChildrenUpdate && canReuseStaticSubtree(el, domVNode)) return;
6076
6077
  updateElementChildren$1(el, children, forceChildrenUpdate);
@@ -6078,9 +6079,10 @@ function applyElementUpdateFromVnode(el, vnode, updateChildren, forceChildrenUpd
6078
6079
  return;
6079
6080
  }
6080
6081
  }
6081
- const usesReactiveChildren = syncReactiveScalarChild(el, props.children ?? domVNode.children, rendererReactiveChildDOMHost);
6082
+ const nextChildren = props.children ?? domVNode.children;
6083
+ const usesReactiveChildren = shouldUpdateChildren ? syncReactiveScalarChild(el, nextChildren, rendererReactiveChildDOMHost) : false;
6082
6084
  syncElementPropBindings(el, domVNode, props, usesReactiveChildren);
6083
- if (updateChildren) {
6085
+ if (shouldUpdateChildren) {
6084
6086
  const children = props.children ?? vnode.children;
6085
6087
  if (usesReactiveChildren) return;
6086
6088
  updateElementChildren$1(el, children, forceChildrenUpdate);
@@ -1,6 +1,6 @@
1
- import { c as RenderableChild } from "../control-D-9LKE3W.js";
2
- import { r as JSXElement, s as Props } from "../jsx-CP0gmYwJ.js";
3
- import { A as RouteQuery, B as RouteSnapshot, C as RouteMeta, D as RouteParams, E as RouteOptions, F as RouteRenderResult, I as RouteRequestOptions, L as RouteRequestResult, M as RouteRef, N as RouteRefSearch, O as RoutePathParams, P as RouteRegistry, R as RouteSearch, S as RouteMatch, T as RouteMode, _ as RouteContext, a as AccessRedirectDecision, b as RouteHandler, c as LayoutScopeRecord, d as ParsedSegment, f as RegisterRoutesOptions, g as RouteComponent, h as RouteAuthResolver, i as AccessDenyStatus, j as RouteRecord, k as RoutePolicy, l as PageHelperOptions, m as RouteAuthOptions, n as AccessDecision, o as AccessRedirectStatus, p as Route, r as AccessDenyDecision, s as GroupHelperOptions, t as AccessAllowDecision, u as PageScopeRecord, v as RouteDefinition, w as RouteMetaSource, x as RouteManifest, y as RouteDestination, z as RouteSearchValue } from "../router-DGbBBIB-.js";
1
+ import { c as RenderableChild } from "../control-CMzFPMjr.js";
2
+ import { r as JSXElement, s as Props } from "../jsx-Dvr2SGRG.js";
3
+ import { A as RouteQuery, B as RouteSnapshot, C as RouteMeta, D as RouteParams, E as RouteOptions, F as RouteRenderResult, I as RouteRequestOptions, L as RouteRequestResult, M as RouteRef, N as RouteRefSearch, O as RoutePathParams, P as RouteRegistry, R as RouteSearch, S as RouteMatch, T as RouteMode, _ as RouteContext, a as AccessRedirectDecision, b as RouteHandler, c as LayoutScopeRecord, d as ParsedSegment, f as RegisterRoutesOptions, g as RouteComponent, h as RouteAuthResolver, i as AccessDenyStatus, j as RouteRecord, k as RoutePolicy, l as PageHelperOptions, m as RouteAuthOptions, n as AccessDecision, o as AccessRedirectStatus, p as Route, r as AccessDenyDecision, s as GroupHelperOptions, t as AccessAllowDecision, u as PageScopeRecord, v as RouteDefinition, w as RouteMetaSource, x as RouteManifest, y as RouteDestination, z as RouteSearchValue } from "../router-Dz7ZoLja.js";
4
4
  import { a as RouteQueryUpdates, c as NavigateOptions, d as ScrollRestorationOptions, i as RouteQueryUpdater, l as HistoryScrollBehavior, n as RouteQueryParamInput, o as UpdateRouteQueryOptions, r as RouteQueryParamValue, s as updateRouteQuery, t as navigate, u as NavigationScrollBehavior } from "../navigate-BVDCzOuB.js";
5
5
  import { AuthContext, AuthContext as AuthContext$1, AuthRequirement, AuthRequirement as AuthRequirement$1 } from "@askrjs/auth";
6
6
  import { ObjectSchema } from "@askrjs/schema";
@@ -1,7 +1,7 @@
1
- import { S as route, _ as fallback, a as resolveRouteMeta, b as page, d as clearRoutes, f as createRouteRegistry, i as reconcileRouteMeta, m as currentRoute, n as navigate, o as serializeRouteMeta, p as getManifest, r as updateRouteQuery, v as group, x as registerRoutes, y as index } from "../navigate-DLi79IZr.js";
1
+ import { S as route, _ as fallback, a as resolveRouteMeta, b as page, d as clearRoutes, f as createRouteRegistry, i as reconcileRouteMeta, m as currentRoute, n as navigate, o as serializeRouteMeta, p as getManifest, r as updateRouteQuery, v as group, x as registerRoutes, y as index } from "../navigate-CaFA0DdW.js";
2
2
  import { jsx } from "../jsx-runtime.js";
3
3
  import { D as getRoutes } from "../route-matching-vJpvLVbX.js";
4
- import { S as lazy, a as resolveDeferredValues, f as resolveRouteRequest, i as isDeferred, n as Resolve, p as currentAuth, r as defer, s as routeData, v as Outlet } from "../deferred-BeNnjR4r.js";
4
+ import { S as lazy, a as resolveDeferredValues, f as resolveRouteRequest, i as isDeferred, n as Resolve, p as currentAuth, r as defer, s as routeData, v as Outlet } from "../deferred-vBQJwHl5.js";
5
5
  import { o as mergeProps } from "../compose-ref-Cc_YkUpM.js";
6
6
  import { t as applyInteractionPolicy } from "../interactions-w7gQN4ha.js";
7
7
  //#region src/router/policy.ts
@@ -1,6 +1,6 @@
1
- import { c as RenderableChild } from "./control-D-9LKE3W.js";
1
+ import { c as RenderableChild } from "./control-CMzFPMjr.js";
2
2
  import { D as QueryPrefetchContext, u as CoreTelemetry } from "./index-Bki2rqcr.js";
3
- import { t as ActionDescriptor } from "./index-YLt-Qg_P.js";
3
+ import { t as ActionDescriptor } from "./index-Bjm0__Rr.js";
4
4
  import { AuthContext, AuthRequirement } from "@askrjs/auth";
5
5
  import { InferSchema, ObjectSchema } from "@askrjs/schema";
6
6
 
@@ -1,5 +1,5 @@
1
- import { c as RenderableChild, d as DocumentRenderContext, f as DocumentRenderer, s as ComponentFunction, u as DocumentRenderArgs } from "../control-D-9LKE3W.js";
2
- import { E as RouteOptions, O as RoutePathParams, P as RouteRegistry, b as RouteHandler, k as RoutePolicy } from "../router-DGbBBIB-.js";
1
+ import { c as RenderableChild, d as DocumentRenderContext, f as DocumentRenderer, s as ComponentFunction, u as DocumentRenderArgs } from "../control-CMzFPMjr.js";
2
+ import { E as RouteOptions, O as RoutePathParams, P as RouteRegistry, b as RouteHandler, k as RoutePolicy } from "../router-Dz7ZoLja.js";
3
3
  import { AuthRequirement } from "@askrjs/auth";
4
4
  //#region src/ssg/types.d.ts
5
5
  type SSGMode = 'full' | 'incremental';
package/dist/ssg/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import "../access-ePqdQqkV.js";
2
- import { a as resolveDeferredValues, b as getRenderHandler, c as bindResolvedRouteData } from "../deferred-BeNnjR4r.js";
2
+ import { a as resolveDeferredValues, b as getRenderHandler, c as bindResolvedRouteData } from "../deferred-vBQJwHl5.js";
3
3
  import { n as renderDocument } from "../ssr-CbQO5xd3.js";
4
- import { n as renderToString } from "../ssr-CbU-1UHm.js";
4
+ import { n as renderToString } from "../ssr-CAYo-kNy.js";
5
5
  import * as fs from "node:fs/promises";
6
6
  import * as pathModule from "node:path";
7
7
  import * as os from "node:os";
@@ -1,7 +1,7 @@
1
- import { c as RenderableChild, d as DocumentRenderContext, f as DocumentRenderer, p as SSRData, u as DocumentRenderArgs } from "../control-D-9LKE3W.js";
2
- import { r as JSXElement, s as Props } from "../jsx-CP0gmYwJ.js";
1
+ import { c as RenderableChild, d as DocumentRenderContext, f as DocumentRenderer, p as SSRData, u as DocumentRenderArgs } from "../control-CMzFPMjr.js";
2
+ import { r as JSXElement, s as Props } from "../jsx-Dvr2SGRG.js";
3
3
  import { D as QueryPrefetchContext, n as ServerQueryRegistry, u as CoreTelemetry, v as DataRuntime } from "../index-Bki2rqcr.js";
4
- import { L as RouteRequestResult, P as RouteRegistry, a as AccessRedirectDecision, b as RouteHandler, j as RouteRecord, m as RouteAuthOptions, p as Route, r as AccessDenyDecision, x as RouteManifest } from "../router-DGbBBIB-.js";
4
+ import { L as RouteRequestResult, P as RouteRegistry, a as AccessRedirectDecision, b as RouteHandler, j as RouteRecord, m as RouteAuthOptions, p as Route, r as AccessDenyDecision, x as RouteManifest } from "../router-Dz7ZoLja.js";
5
5
  import { AuthContext } from "@askrjs/auth";
6
6
 
7
7
  //#region src/common/page-render-envelope.d.ts
@@ -50,6 +50,7 @@ interface RenderContext {
50
50
  renderData: PageRenderEnvelope | null;
51
51
  hydrationData: PageRenderEnvelope | null;
52
52
  deferredBoundaries: DeferredBoundaryRegistration[];
53
+ cspNonce?: string;
53
54
  }
54
55
  declare function createRenderContext(seed?: number, opts?: {
55
56
  url?: string;
@@ -63,6 +64,7 @@ declare function createRenderContext(seed?: number, opts?: {
63
64
  queryPrefetch?: QueryPrefetchContext;
64
65
  framework?: Readonly<Record<string, unknown>>;
65
66
  envelope?: PageRenderEnvelope;
67
+ cspNonce?: string;
66
68
  }): RenderContext;
67
69
  /**
68
70
  * Run a function with the given render context.
@@ -99,6 +101,7 @@ type RouteRenderOptions = SSRRouteSource & {
99
101
  queryPrefetch?: QueryPrefetchContext;
100
102
  telemetry?: Pick<CoreTelemetry, 'ssrRender'>; /** @internal Precomposed page state used by hydration verification. */
101
103
  envelope?: PageRenderEnvelope;
104
+ cspNonce?: string;
102
105
  };
103
106
  type RouteStreamOptions = RouteRenderOptions & {
104
107
  onChunk(html: string): void;
@@ -167,6 +170,7 @@ declare function renderToStringSync(component: (props?: Record<string, unknown>)
167
170
  seed?: number;
168
171
  data?: SSRData; /** @internal A composed page render envelope. */
169
172
  envelope?: PageRenderEnvelope;
173
+ cspNonce?: string;
170
174
  }): string;
171
175
  //#endregion
172
176
  //#region src/ssr/render-resolved.d.ts
@@ -184,6 +188,7 @@ declare function renderResolvedToStringSync(opts: {
184
188
  data?: SSRData;
185
189
  dataRuntime?: DataRuntime;
186
190
  envelope?: PageRenderEnvelope;
191
+ cspNonce?: string;
187
192
  };
188
193
  }): string;
189
194
  //#endregion
@@ -204,6 +209,7 @@ interface RenderRouteRequestOptions {
204
209
  queryPrefetch?: QueryPrefetchContext;
205
210
  queryRegistry?: ServerQueryRegistry;
206
211
  telemetry?: CoreTelemetry;
212
+ cspNonce?: string;
207
213
  }
208
214
  type RenderRouteRequestResult = {
209
215
  kind: 'render';
package/dist/ssr/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { u as SSRDataMissingError } from "../render-context-Clw3rFiO.js";
2
- import { a as renderResolvedToStringSync, c as createRenderContext, d as withRenderContextAsync, i as renderRouteRequestToString, l as getRenderContext, n as renderToString, o as renderToStringSync, r as renderRouteRequest, s as resolveRequest, t as renderToStream, u as withRenderContext } from "../ssr-CbU-1UHm.js";
2
+ import { a as renderResolvedToStringSync, c as createRenderContext, d as withRenderContextAsync, i as renderRouteRequestToString, l as getRenderContext, n as renderToString, o as renderToStringSync, r as renderRouteRequest, s as resolveRequest, t as renderToStream, u as withRenderContext } from "../ssr-CAYo-kNy.js";
3
3
  export { SSRDataMissingError, createRenderContext, getRenderContext, renderResolvedToStringSync, renderRouteRequest, renderRouteRequestToString, renderToStream, renderToString, renderToStringSync, resolveRequest, withRenderContext, withRenderContextAsync };
@@ -9,10 +9,11 @@ import { g as evaluateShowState, h as evaluateCaseState, i as evaluateForState,
9
9
  import { c as stopRenderPhase$1, o as startRenderPhase$1, t as configureRenderContextProvider, u as SSRDataMissingError } from "./render-context-Clw3rFiO.js";
10
10
  import { a as disposeDefaultPortalScope, t as DefaultPortal } from "./portal-D2tPWNrC.js";
11
11
  import { t as getPublicAttributeName } from "./attr-names-CjhzmHOn.js";
12
+ import { r as validateCspNonce, t as CspNonceScope } from "./csp-nonce-C-8E85El.js";
12
13
  import { t as createDataRuntime } from "./data-runtime-SJ1BSUvk.js";
13
14
  import { c as withTelemetry, i as dehydrateDataRuntime, t as createQueryPrefetchContext } from "./query-registry-CQIT4mXr.js";
14
15
  import { a as resolveRouteFromRoutes, t as _resolveRouteMatchFromRoutes } from "./route-matching-vJpvLVbX.js";
15
- import { f as resolveRouteRequest, g as isPageRenderEnvelope, h as isEmptyPageRenderEnvelope, i as isDeferred, m as createPageRenderEnvelope, t as DEFERRED_BOUNDARY, x as _preloadRouteHandler } from "./deferred-BeNnjR4r.js";
16
+ import { f as resolveRouteRequest, g as isPageRenderEnvelope, h as isEmptyPageRenderEnvelope, i as isDeferred, m as createPageRenderEnvelope, t as DEFERRED_BOUNDARY, x as _preloadRouteHandler } from "./deferred-vBQJwHl5.js";
16
17
  import { n as renderDocument, t as SSR_RENDER_DATA_ATTR } from "./ssr-CbQO5xd3.js";
17
18
  //#region src/ssr/escape.ts
18
19
  /**
@@ -260,7 +261,8 @@ function createRenderContext(seed = 12345, opts = {}) {
260
261
  keyCounter: 0,
261
262
  renderData: envelope,
262
263
  hydrationData: envelope,
263
- deferredBoundaries: []
264
+ deferredBoundaries: [],
265
+ cspNonce: opts.cspNonce
264
266
  };
265
267
  }
266
268
  /**
@@ -520,6 +522,7 @@ function resolveSSRRouteSource(source) {
520
522
  }
521
523
  function resolveSSRRouteRender(opts) {
522
524
  const { seed = 12345, data, document } = opts;
525
+ const cspNonce = validateCspNonce(opts.cspNonce);
523
526
  const routeTable = resolveSSRRouteSource(opts);
524
527
  const resolvedRoute = resolvePolicyAwareSSRRoute(opts, routeTable);
525
528
  const requestUrl = new URL(resolvedRoute.url, "http://localhost");
@@ -530,7 +533,8 @@ function resolveSSRRouteRender(opts) {
530
533
  routes: routeTable,
531
534
  dataRuntime: opts.dataRuntime,
532
535
  queryPrefetch: opts.queryPrefetch,
533
- envelope: opts.envelope
536
+ envelope: opts.envelope,
537
+ cspNonce
534
538
  });
535
539
  return {
536
540
  url: resolvedRoute.url,
@@ -540,7 +544,8 @@ function resolveSSRRouteRender(opts) {
540
544
  seed,
541
545
  data,
542
546
  ctx,
543
- document
547
+ document,
548
+ cspNonce
544
549
  };
545
550
  }
546
551
  function buildDocumentRenderArgs(resolved, appHtml) {
@@ -558,7 +563,8 @@ function buildDocumentRenderArgs(resolved, appHtml) {
558
563
  route: {
559
564
  path: resolved.route.path,
560
565
  namespace: resolved.route.namespace
561
- }
566
+ },
567
+ cspNonce: resolved.cspNonce
562
568
  }
563
569
  };
564
570
  }
@@ -800,7 +806,10 @@ function withControlBoundaryChildren(node, render) {
800
806
  const ESCAPED_ATTR_VALUE_CACHE_LIMIT = 512;
801
807
  const escapedAttrValueCache = /* @__PURE__ */ new Map();
802
808
  function isEventHandler(key) {
803
- return key.length >= 3 && key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90;
809
+ return key.length >= 2 && key.slice(0, 2).toLowerCase() === "on";
810
+ }
811
+ function assertAttributeName(name) {
812
+ if (!/^[A-Za-z_:][A-Za-z0-9_.:-]*$/.test(name)) throw new TypeError(`Invalid SSR attribute name: ${JSON.stringify(name)}`);
804
813
  }
805
814
  function getEscapedAttrValue(value) {
806
815
  if (value.length > 64) return escapeAttr(value);
@@ -821,10 +830,11 @@ function renderAttrsDirect(props, sink) {
821
830
  const propsObj = props;
822
831
  for (const key in propsObj) {
823
832
  const value = propsObj[key];
824
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML") continue;
833
+ if (key === "children" || key === "imperativeChildren" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML") continue;
825
834
  if (isEventHandler(key)) continue;
826
835
  if (key.charCodeAt(0) === 95) continue;
827
836
  const attrName = getPublicAttributeName(key);
837
+ assertAttributeName(attrName);
828
838
  if (attrName === "style") {
829
839
  const css = typeof value === "string" ? value : styleObjToCss(value);
830
840
  if (!css) continue;
@@ -855,7 +865,7 @@ function renderAttrs(props, opts) {
855
865
  const propsObj = props;
856
866
  for (const key in propsObj) {
857
867
  const value = propsObj[key];
858
- if (key === "children") continue;
868
+ if (key === "children" || key === "imperativeChildren") continue;
859
869
  if (key === "key" || key === "ref") continue;
860
870
  if (key === "dangerouslySetInnerHTML") {
861
871
  if (value && typeof value === "object" && "__html" in value) dangerousHtml = String(value.__html);
@@ -864,6 +874,7 @@ function renderAttrs(props, opts) {
864
874
  if (isEventHandler(key)) continue;
865
875
  if (key.charCodeAt(0) === 95) continue;
866
876
  const attrName = key === "class" ? "class" : getPublicAttributeName(key);
877
+ assertAttributeName(attrName);
867
878
  if (attrName === "style") {
868
879
  const css = typeof value === "string" ? value : styleObjToCss(value);
869
880
  if (css === null || css === "") continue;
@@ -1066,6 +1077,7 @@ function renderNodeSync(node, ctx) {
1066
1077
  throw new Error(`renderNodeSync: unsupported VNode symbol type: ${String(type)}`);
1067
1078
  }
1068
1079
  const typeStr = type;
1080
+ assertElementName(typeStr);
1069
1081
  if (VOID_ELEMENTS.has(typeStr)) return `<${typeStr}${renderAttrs(props)} />`;
1070
1082
  const maybeDangerous = props?.dangerouslySetInnerHTML;
1071
1083
  if (maybeDangerous !== void 0 && maybeDangerous !== null) {
@@ -1118,6 +1130,7 @@ function renderNodeSyncToSink(node, sink, ctx) {
1118
1130
  throw new Error(`renderNodeSyncToSink: unsupported VNode symbol type: ${String(type)}`);
1119
1131
  }
1120
1132
  const typeStr = type;
1133
+ assertElementName(typeStr);
1121
1134
  if (VOID_ELEMENTS.has(typeStr)) {
1122
1135
  sinkWrite2(sink, "<", typeStr);
1123
1136
  renderAttrsDirect(props, sink);
@@ -1171,14 +1184,19 @@ function renderNodeSyncToSink(node, sink, ctx) {
1171
1184
  sinkWrite3(sink, "</", typeStr, ">");
1172
1185
  }
1173
1186
  function renderToStringSync(component, props, options) {
1174
- const ctx = createRenderContext(options?.seed ?? 12345, {
1187
+ const seed = options?.seed ?? 12345;
1188
+ const nonce = validateCspNonce(options?.cspNonce);
1189
+ const ctx = createRenderContext(seed, {
1175
1190
  data: options?.data,
1176
1191
  envelope: options?.envelope
1177
1192
  });
1178
1193
  return withRenderContext(ctx, () => {
1179
1194
  startRenderPhase(ctx.renderData);
1180
1195
  try {
1181
- const node = renderSyncComponentRoot(component, props || {}, ctx);
1196
+ const node = renderSyncComponentRoot(nonce === void 0 ? component : () => CspNonceScope({
1197
+ value: nonce,
1198
+ children: () => component(props)
1199
+ }), props || {}, ctx);
1182
1200
  if (!node) throw new Error("renderToStringSync: wrapped component returned empty");
1183
1201
  const sink = new StringSink();
1184
1202
  renderNodeSyncToSink(node, sink, ctx);
@@ -1199,7 +1217,10 @@ function renderSSRRouteAppToSink(input) {
1199
1217
  withRenderContext(ctx, () => {
1200
1218
  startRenderPhase(ctx.renderData);
1201
1219
  try {
1202
- renderRenderableSyncToSink(executeComponentSync(route.handler, params, ctx), sink, ctx);
1220
+ renderRenderableSyncToSink(executeComponentSync(ctx.cspNonce === void 0 ? route.handler : () => CspNonceScope({
1221
+ value: ctx.cspNonce,
1222
+ children: () => route.handler(params)
1223
+ }), params, ctx), sink, ctx);
1203
1224
  if (ctx.deferredBoundaries.length === 0) sink.write(serializeHydrationRenderData(ctx.hydrationData ?? data, ctx.dataRuntime));
1204
1225
  } finally {
1205
1226
  try {
@@ -1210,6 +1231,9 @@ function renderSSRRouteAppToSink(input) {
1210
1231
  }
1211
1232
  });
1212
1233
  }
1234
+ function assertElementName(name) {
1235
+ if (!/^[A-Za-z][A-Za-z0-9._:-]*$/.test(name)) throw new TypeError(`Invalid SSR element name: ${JSON.stringify(name)}`);
1236
+ }
1213
1237
  //#endregion
1214
1238
  //#region src/ssr/render-resolved.ts
1215
1239
  function sameRouteParams(left, right) {
@@ -1237,7 +1261,8 @@ function renderResolvedToStringSync(opts) {
1237
1261
  seed: options?.seed,
1238
1262
  data: options?.data,
1239
1263
  dataRuntime: options?.dataRuntime,
1240
- envelope: options?.envelope
1264
+ envelope: options?.envelope,
1265
+ cspNonce: options?.cspNonce
1241
1266
  });
1242
1267
  }
1243
1268
  //#endregion
@@ -1264,17 +1289,18 @@ function settleWithSignal(promise, signal) {
1264
1289
  function stripHydrationPayload(html) {
1265
1290
  return html.replace(/<script type="application\/json" data-askr-render-data="true">[\s\S]*?<\/script>$/, "");
1266
1291
  }
1267
- function renderBoundary(boundary, state, payload, seed, data) {
1292
+ function renderBoundary(boundary, state, payload, seed, data, cspNonce) {
1268
1293
  return stripHydrationPayload(renderToStringSync(() => state === "fulfilled" ? boundary.fulfilled(payload) : boundary.rejected(payload), {}, {
1269
1294
  seed,
1270
- envelope: data ?? void 0
1295
+ envelope: data ?? void 0,
1296
+ cspNonce
1271
1297
  }));
1272
1298
  }
1273
- function patchChunk(id, html) {
1299
+ function patchChunk(id, html, cspNonce) {
1274
1300
  const selector = `askr-resolve[data-askr-deferred=${JSON.stringify(id)}]`;
1275
- return `<template data-askr-deferred-patch="${id}">${html}</template><script data-askr-deferred-apply="${id}">(function(s){var t=s.previousElementSibling;var b=document.querySelector(${JSON.stringify(selector)});if(b&&t){b.replaceWith(t.content.cloneNode(true));}if(t)t.remove();s.remove();})(document.currentScript)<\/script>`;
1301
+ return `<template data-askr-deferred-patch="${id}">${html}</template><script${cspNonce ? ` nonce="${cspNonce}"` : ""} data-askr-deferred-apply="${id}">(function(s){var t=s.previousElementSibling;var b=document.querySelector(${JSON.stringify(selector)});if(b&&t){b.replaceWith(t.content.cloneNode(true));}if(t)t.remove();s.remove();})(document.currentScript)<\/script>`;
1276
1302
  }
1277
- function createDeferredRenderStream(initialHtml, boundaries, signal, seed, data, runtime) {
1303
+ function createDeferredRenderStream(initialHtml, boundaries, signal, seed, data, runtime, cspNonce) {
1278
1304
  const encoder = new TextEncoder();
1279
1305
  const local = new AbortController();
1280
1306
  let cancelled = false;
@@ -1310,13 +1336,13 @@ function createDeferredRenderStream(initialHtml, boundaries, signal, seed, data,
1310
1336
  boundaryIndex += 1;
1311
1337
  try {
1312
1338
  const value = await settleWithSignal(boundary.promise, local.signal);
1313
- if (!cancelled && !closed) controller.enqueue(encoder.encode(patchChunk(boundary.id, renderBoundary(boundary, "fulfilled", value, seed, data))));
1339
+ if (!cancelled && !closed) controller.enqueue(encoder.encode(patchChunk(boundary.id, renderBoundary(boundary, "fulfilled", value, seed, data, cspNonce), cspNonce)));
1314
1340
  } catch (error) {
1315
1341
  if (local.signal.aborted) {
1316
1342
  if (!cancelled && !closed) close(controller);
1317
1343
  return;
1318
1344
  }
1319
- if (!cancelled && !closed) controller.enqueue(encoder.encode(patchChunk(boundary.id, renderBoundary(boundary, "rejected", error, seed, data))));
1345
+ if (!cancelled && !closed) controller.enqueue(encoder.encode(patchChunk(boundary.id, renderBoundary(boundary, "rejected", error, seed, data, cspNonce), cspNonce)));
1320
1346
  }
1321
1347
  return;
1322
1348
  }
@@ -1344,6 +1370,7 @@ async function renderRouteRequestToString(options) {
1344
1370
  };
1345
1371
  }
1346
1372
  async function renderRouteRequestInternal(options) {
1373
+ const cspNonce = validateCspNonce(options.cspNonce);
1347
1374
  const manifest = options.manifest ?? options.registry?.manifest;
1348
1375
  if (!manifest) throw new Error("renderRouteRequestToString requires a route manifest or registry.");
1349
1376
  const signal = options.signal ?? options.request?.signal ?? new AbortController().signal;
@@ -1364,7 +1391,8 @@ async function renderRouteRequestInternal(options) {
1364
1391
  signal,
1365
1392
  dataRuntime: runtime,
1366
1393
  queryPrefetch: prefetch,
1367
- mode: "ssr"
1394
+ mode: "ssr",
1395
+ cspNonce
1368
1396
  });
1369
1397
  return withTelemetry(options.telemetry?.ssrRender, {}, () => withRenderContextAsync(context, async () => {
1370
1398
  const resolved = await resolveRouteRequest(options.url, {
@@ -1395,7 +1423,7 @@ async function renderRouteRequestInternal(options) {
1395
1423
  const result = {
1396
1424
  kind: "render",
1397
1425
  html,
1398
- ...boundaries.length > 0 ? { stream: createDeferredRenderStream(html, boundaries, signal, options.seed, context.hydrationData, runtime) } : {},
1426
+ ...boundaries.length > 0 ? { stream: createDeferredRenderStream(html, boundaries, signal, options.seed, context.hydrationData, runtime, cspNonce) } : {},
1399
1427
  params: resolved.params
1400
1428
  };
1401
1429
  if (resolved.record) Object.defineProperty(result, "record", {
@@ -1,5 +1,5 @@
1
1
  import { C as Query, k as QueryStaleReason } from "../index-Bki2rqcr.js";
2
- import { S as RouteMatch, p as Route, x as RouteManifest } from "../router-DGbBBIB-.js";
2
+ import { S as RouteMatch, p as Route, x as RouteManifest } from "../router-Dz7ZoLja.js";
3
3
 
4
4
  //#region src/testing/index.d.ts
5
5
  type MockRefresh = () => void | Promise<void>;
@@ -1,4 +1,4 @@
1
- import { a as IntrinsicFallbackProps, o as KnownIntrinsicElementProps, r as JSXElement, s as Props } from "./jsx-CP0gmYwJ.js";
1
+ import { a as IntrinsicFallbackProps, o as KnownIntrinsicElementProps, r as JSXElement, s as Props } from "./jsx-Dvr2SGRG.js";
2
2
 
3
3
  //#region src/jsx/types.d.ts
4
4
  declare global {
@@ -1,5 +1,5 @@
1
1
  import { t as SSR_RENDER_DATA_ATTR } from "./ssr-CbQO5xd3.js";
2
- import { a as renderResolvedToStringSync } from "./ssr-CbU-1UHm.js";
2
+ import { a as renderResolvedToStringSync } from "./ssr-CAYo-kNy.js";
3
3
  //#region src/ssr/verify-hydration.ts
4
4
  function normalizeHydrationHtml(html) {
5
5
  const template = document.createElement("template");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askrjs/askr",
3
- "version": "0.0.61",
3
+ "version": "0.0.64",
4
4
  "description": "Actor-backed deterministic UI framework",
5
5
  "keywords": [
6
6
  "askr",
@@ -1,4 +0,0 @@
1
- //#region src/common/router-internal.ts
2
- const ROUTE_ROOT_COMPONENT = Symbol.for("askr.route-root-component");
3
- //#endregion
4
- export { ROUTE_ROOT_COMPONENT as t };