@farm.js/islx 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +56 -26
  3. package/SPEC.md +5 -4
  4. package/dist/_chunks/{actions-C-IwUCKU.mjs → actions-DAzd4PpV.mjs} +2 -2
  5. package/dist/_chunks/{actions-CvQ0-zjg.mjs → actions-DzIPDecd.mjs} +2 -2
  6. package/dist/_chunks/{codec-C8to-RQW.mjs → codec-DDpUvgRo.mjs} +1 -1
  7. package/dist/_chunks/{actions-Eutk6UzT.mjs → form-status-CRfnB7WT.mjs} +314 -1
  8. package/dist/_chunks/forms-CCDY9QHC.mjs +63 -0
  9. package/dist/_chunks/{tree-C47p6khN.mjs → island-viWIOM1k.mjs} +501 -8
  10. package/dist/_chunks/{prehydration-B1GLTLdk.mjs → prehydration-zEYsfFxW.mjs} +3 -2
  11. package/dist/_chunks/{schedule-CjoybS3b.mjs → schedule-IK9_RwZC.mjs} +13 -4
  12. package/dist/_chunks/{tree-B4RMU2UX.d.mts → tree-CV13RsJv.d.mts} +8 -1
  13. package/dist/_chunks/{values-37UIzxM0.mjs → values-gxhIei_m.mjs} +2 -2
  14. package/dist/_chunks/{vite-BTzYlEiY.mjs → vite-CHB6B8tP.mjs} +36 -12
  15. package/dist/_chunks/{wire-Dipqh-EB.d.mts → wire-1d6wqOia.d.mts} +16 -1
  16. package/dist/_chunks/{wire-QEQWBr5s.mjs → wire-UUwZlUJZ.mjs} +17 -1
  17. package/dist/boot.d.mts +31 -0
  18. package/dist/boot.mjs +177 -0
  19. package/dist/client.d.mts +2 -1
  20. package/dist/client.mjs +4 -28
  21. package/dist/compiler.d.mts +35 -1
  22. package/dist/compiler.mjs +1 -1
  23. package/dist/index.d.mts +2 -2
  24. package/dist/index.mjs +3 -3
  25. package/dist/react/client.d.mts +2 -2
  26. package/dist/react/client.mjs +88 -19
  27. package/dist/react/server.d.mts +1 -1
  28. package/dist/react/server.mjs +13 -10
  29. package/dist/react.d.mts +6 -2
  30. package/dist/react.mjs +22 -3
  31. package/dist/server.d.mts +5 -0
  32. package/dist/server.mjs +4 -4
  33. package/dist/tanstack-start/server.mjs +3 -3
  34. package/dist/tanstack-start.mjs +1 -1
  35. package/dist/vite.d.mts +16 -1
  36. package/dist/vite.mjs +1 -1
  37. package/package.json +5 -1
  38. package/dist/_chunks/island-DVOr-OUw.mjs +0 -262
@@ -1,5 +1,5 @@
1
- import { i as transformActions, r as hasModuleDirective, t as ActionCompileError } from "./actions-Eutk6UzT.mjs";
2
- import { t as ISLAND_STRATEGIES } from "./schedule-CjoybS3b.mjs";
1
+ import { i as ActionCompileError, n as rewriteFormStatusImports, o as hasModuleDirective, r as inferStrategy, s as transformActions, t as rewriteFormStatusImport } from "./form-status-CRfnB7WT.mjs";
2
+ import { t as ISLAND_STRATEGIES } from "./schedule-IK9_RwZC.mjs";
3
3
  import { randomBytes } from "node:crypto";
4
4
  import path from "node:path";
5
5
  import { walk } from "estree-walker";
@@ -78,12 +78,15 @@ function transformClientModule(options) {
78
78
  throw new ActionCompileError(message, file, code, node.start);
79
79
  };
80
80
  const strategies = readStrategies(program, fail);
81
+ const inference = options.infer && strategies.all === void 0 && strategies.byName.size === 0 ? inferStrategy(file, code, options.infer) : void 0;
82
+ const inferred = (name) => options.strategy?.(name) === void 0 && inference?.strategy === "interaction";
81
83
  const strategyOf = (name) => {
82
84
  const configured = options.strategy?.(name);
83
85
  if (configured !== void 0 && !ISLAND_STRATEGIES.includes(configured)) throw new Error(`islx: strategy for ${name} must be one of ${ISLAND_STRATEGIES.join(", ")}`);
84
- return configured ?? strategies.byName.get(name) ?? strategies.all ?? "load";
86
+ return configured ?? strategies.byName.get(name) ?? strategies.all ?? (inference?.strategy === "interaction" ? "interaction" : "load");
85
87
  };
86
88
  const output = new MagicString(code);
89
+ rewriteFormStatusImport(program, code, output, options.runtime ?? "@farm.js/islx/react");
87
90
  const wrapped = [];
88
91
  for (const node of program.body ?? []) if (node.type === "ExportNamedDeclaration" && !node.source && node.exportKind !== "type") {
89
92
  const declaration = node.declaration;
@@ -140,7 +143,9 @@ function transformClientModule(options) {
140
143
  const runtime = options.runtime ?? "@farm.js/islx/react";
141
144
  const src = options.reference(relative);
142
145
  const lines = [...wrapped.map(({ local, exportName }, index) => {
143
- return `const $$islx_island_${index} = $$islx_island(${local}, ${src}, ${JSON.stringify(exportName)}, ${JSON.stringify(strategyOf(exportName === "default" ? "default" : exportName))});`;
146
+ const strategy = JSON.stringify(strategyOf(exportName));
147
+ const flags = inferred(exportName) ? ", { inferred: true }" : "";
148
+ return `const $$islx_island_${index} = $$islx_island(${local}, ${src}, ${JSON.stringify(exportName)}, ${strategy}${flags});`;
144
149
  }), `export { ${wrapped.map(({ exportName }, index) => `$$islx_island_${index} as ${exportName}`).join(", ")} };`];
145
150
  const imports = [`import { createIsland as $$islx_island } from ${JSON.stringify(runtime)};`, ...(options.sideEffects ?? []).map((module) => `import ${JSON.stringify(module)};`)];
146
151
  output.prepend(`${imports.join("\n")}\n`);
@@ -154,7 +159,8 @@ function transformClientModule(options) {
154
159
  islands: wrapped.map(({ exportName }) => ({
155
160
  exportName,
156
161
  strategy: strategyOf(exportName)
157
- }))
162
+ })),
163
+ ...inference ? { inference } : {}
158
164
  };
159
165
  }
160
166
  // src/vite.ts
@@ -177,6 +183,8 @@ function transformClientModule(options) {
177
183
  const RUNTIME_ID = "virtual:islx/runtime";
178
184
  /** @internal The browser entry, for a framework whose own entry imports it. */
179
185
  const ENTRY_ID = "virtual:islx/client-entry";
186
+ /** The boot entry: pages start with it, and it loads ENTRY_ID when the page first needs it. */
187
+ const BOOT_ID = "virtual:islx/boot";
180
188
  const LIBRARY_RUNTIME_ID = "virtual:islx/react-for-libraries";
181
189
  const CLIENT_HOOKS_ID = "virtual:islx/hooks-client";
182
190
  const SERVER_HOOKS_ID = "virtual:islx/hooks-server";
@@ -244,6 +252,7 @@ function serializeHooks(hooks, where, parse) {
244
252
  * build until the browser build names them. */
245
253
  const ENTRY_PLACEHOLDER = "__islx_client_entry_url__";
246
254
  const MODULES_PLACEHOLDER = "__islx_client_modules__";
255
+ const BOOT_PLACEHOLDER = "__islx_boot_url__";
247
256
  const SCRIPT = /\.[cm]?[jt]sx?$/;
248
257
  async function createParser() {
249
258
  const withErrors = (result) => Object.assign(result.program, { errors: result.errors ?? [] });
@@ -315,6 +324,7 @@ function islx(options = {}, host = {}) {
315
324
  const discovered = /* @__PURE__ */ new Set();
316
325
  /** The browser entry's URL, once the browser build named it. */
317
326
  let entryUrl;
327
+ let bootUrl;
318
328
  /** The files each client module needs, once the browser build named them. */
319
329
  const moduleFiles = {};
320
330
  /** Whether the browser build ran first (a framework that orders the build). */
@@ -355,7 +365,8 @@ function islx(options = {}, host = {}) {
355
365
  outDir: clientBuild?.outDir ?? "dist/client",
356
366
  rollupOptions: { input: host.frameworkEntry ? input : {
357
367
  ...typeof input === "string" ? { index: input } : Array.isArray(input) ? Object.fromEntries(input.map((entry, index) => [`input${index}`, entry])) : input,
358
- "islx-entry": ENTRY_ID
368
+ "islx-entry": ENTRY_ID,
369
+ ...options.boot === false ? {} : { "islx-boot": BOOT_ID }
359
370
  } }
360
371
  }
361
372
  } }
@@ -368,17 +379,18 @@ function islx(options = {}, host = {}) {
368
379
  },
369
380
  resolveId(id) {
370
381
  if (id === LIBRARY_RUNTIME_ID) return this.resolve("@farm.js/islx/react", path.join(config.root, "package.json"), { skipSelf: true });
371
- if (id === RUNTIME_ID || id === "virtual:islx/client-entry" || id === CLIENT_HOOKS_ID || id === SERVER_HOOKS_ID) return `\0${id}`;
382
+ if (id === RUNTIME_ID || id === "virtual:islx/client-entry" || id === "virtual:islx/boot" || id === CLIENT_HOOKS_ID || id === SERVER_HOOKS_ID) return `\0${id}`;
372
383
  },
373
384
  async load(id) {
374
385
  if (id === `\0${RUNTIME_ID}`) {
375
386
  const entry = host.frameworkEntry ? void 0 : !isBuild() ? `${config.base}@id/__x00__${ENTRY_ID}` : clientBuilt ? entryUrl : ENTRY_PLACEHOLDER;
387
+ const boot = host.frameworkEntry || options.boot === false ? void 0 : !isBuild() ? `${config.base}@id/__x00__${BOOT_ID}` : clientBuilt ? bootUrl : BOOT_PLACEHOLDER;
376
388
  const modules = !isBuild() ? "{}" : clientBuilt ? JSON.stringify(moduleFiles) : `JSON.parse(${JSON.stringify(MODULES_PLACEHOLDER)})`;
377
389
  return [
378
390
  ...host.frameworkRender ? [`import "@farm.js/islx/react/server";`] : [],
379
391
  `import { setBuildDefaults, setServerHooks } from "@farm.js/islx/server";`,
380
392
  `import hooks from ${JSON.stringify(SERVER_HOOKS_ID)};`,
381
- `setBuildDefaults({ entry: ${JSON.stringify(entry)}, key: ${JSON.stringify(buildKey)}, modules: ${modules} });`,
393
+ `setBuildDefaults({ entry: ${JSON.stringify(entry)}, boot: ${JSON.stringify(boot)}, key: ${JSON.stringify(buildKey)}, modules: ${modules} });`,
382
394
  `setServerHooks(hooks);`
383
395
  ].join("\n");
384
396
  }
@@ -389,6 +401,7 @@ function islx(options = {}, host = {}) {
389
401
  if (typeof hooks === "string") return `export { default } from ${JSON.stringify(path.resolve(config.root, hooks))};`;
390
402
  return serializeHooks(hooks, where, parse);
391
403
  }
404
+ if (id === `\0virtual:islx/boot`) return `import { startBoot } from "@farm.js/islx/boot";\nstartBoot();\n`;
392
405
  if (id === `\0virtual:islx/client-entry`) {
393
406
  const load = isBuild() ? `const modules = {\n${(await clientInputs()).map((relative) => ` ${JSON.stringify(relative)}: () => import(${JSON.stringify(path.resolve(config.root, relative))}),`).join("\n")}\n};\nconst load = (src) => modules[src] ? modules[src]() : Promise.reject(new Error("islx: no client module " + src));` : `const root = new URL(${JSON.stringify(`file://${toPosix(config.root)}/`)});\nconst load = (src) => import(/* @vite-ignore */ src.startsWith("../") ? "/@fs" + new URL(src, root).pathname : ${JSON.stringify(config.base)} + src);`;
394
407
  return [
@@ -428,8 +441,10 @@ function islx(options = {}, host = {}) {
428
441
  },
429
442
  sideEffects: [RUNTIME_ID],
430
443
  directive: clientDirective,
431
- ...library ? { runtime: LIBRARY_RUNTIME_ID } : {}
444
+ ...library ? { runtime: LIBRARY_RUNTIME_ID } : {},
445
+ ...options.infer !== false && !library ? { infer: { parse } } : {}
432
446
  });
447
+ for (const read of island?.inference?.files ?? []) if (read !== file) this.addWatchFile(read);
433
448
  if (island) {
434
449
  if (!library) transformActions({
435
450
  code,
@@ -446,6 +461,14 @@ function islx(options = {}, host = {}) {
446
461
  }
447
462
  }
448
463
  if (library) return null;
464
+ if (!server && !code.includes(directives.server) && hasModuleDirective(code, clientDirective) && !excluded(relative)) {
465
+ const rewritten = rewriteFormStatusImports({
466
+ code,
467
+ id: file,
468
+ parse: parseFile
469
+ });
470
+ if (rewritten) return rewritten;
471
+ }
449
472
  const actions = transformActions({
450
473
  code,
451
474
  id: file,
@@ -484,9 +507,9 @@ function islx(options = {}, host = {}) {
484
507
  const outDir = path.resolve(config.root, environment.config.build.outDir);
485
508
  for (const file of await listOutput(outDir)) {
486
509
  const source = await readFile(file, "utf8");
487
- if (!source.includes(ENTRY_PLACEHOLDER) && !source.includes(MODULES_PLACEHOLDER)) continue;
510
+ if (!source.includes(ENTRY_PLACEHOLDER) && !source.includes(MODULES_PLACEHOLDER) && !source.includes(BOOT_PLACEHOLDER)) continue;
488
511
  const modules = JSON.stringify(JSON.stringify(moduleFiles)).slice(1, -1);
489
- await writeFile(file, source.replaceAll(ENTRY_PLACEHOLDER, entryUrl).replaceAll(MODULES_PLACEHOLDER, modules));
512
+ await writeFile(file, source.replaceAll(ENTRY_PLACEHOLDER, entryUrl).replaceAll(MODULES_PLACEHOLDER, modules).replaceAll(BOOT_PLACEHOLDER, bootUrl ?? ""));
490
513
  }
491
514
  }
492
515
  },
@@ -496,6 +519,7 @@ function islx(options = {}, host = {}) {
496
519
  for (const chunk of Object.values(bundle)) {
497
520
  if (chunk.type !== "chunk" || !chunk.facadeModuleId) continue;
498
521
  if (chunk.isEntry && chunk.facadeModuleId === `\0virtual:islx/client-entry`) entryUrl = url(chunk.fileName);
522
+ else if (chunk.isEntry && chunk.facadeModuleId === `\0virtual:islx/boot`) bootUrl = url(chunk.fileName);
499
523
  else if (chunk.isDynamicEntry && !chunk.facadeModuleId.startsWith("\0")) moduleFiles[relativeOf(chunk.facadeModuleId)] = [chunk.fileName, ...chunk.imports].map(url);
500
524
  }
501
525
  clientBuilt = true;
@@ -503,4 +527,4 @@ function islx(options = {}, host = {}) {
503
527
  }
504
528
  ];
505
529
  }
506
- export { serializeHooks as i, islx as n, resolveDirectives as r, ENTRY_ID as t };
530
+ export { serializeHooks as a, resolveDirectives as i, ENTRY_ID as n, islx as r, BOOT_ID as t };
@@ -12,12 +12,22 @@
12
12
  declare const ISLAND_ELEMENT = "f-island";
13
13
  /** The script type of an island's props; its `for` attribute names the island. */
14
14
  declare const PROPS_SCRIPT_TYPE = "f/props";
15
+ /**
16
+ * On a props script: the id React gave the island's position on the server, so the browser
17
+ * hydrates the island where the server rendered it and `useId` matches.
18
+ */
19
+ declare const ID_POSITION_ATTRIBUTE = "ids";
15
20
  /** The script type of a value sent once; its `name` attribute is the value's key. */
16
21
  declare const VALUE_SCRIPT_TYPE = "f/value";
17
22
  /** Set on an island once it hydrated (and its held interaction was replayed). */
18
23
  declare const HYDRATED_ATTRIBUTE = "hydrated";
19
24
  /** The element that keeps server output passed to an island as children. */
20
25
  declare const SLOT_ELEMENT = "f-slot";
26
+ /**
27
+ * After an island's props: `<template for>` holding the `<f-slot>`s the island did not place when
28
+ * the server rendered it, which the browser shows when the island places them.
29
+ */
30
+ declare const SLOT_TEMPLATE_ELEMENT = "template";
21
31
  /** The script type of a page's server tree, rebuilt in the browser without the page's HTML. */
22
32
  declare const TREE_SCRIPT_TYPE = "f/tree";
23
33
  /** The script type of a server tree chunk that streamed in after the tree. */
@@ -41,6 +51,11 @@ declare const TAG_BOUND = "b";
41
51
  declare const REFERENCE_TAG = "r";
42
52
  /** `{"$":"s","v":name}`: a slot. */
43
53
  declare const SLOT_TAG = "s";
54
+ /**
55
+ * On a slot reference: `1` when the slot carries a server tree (`<script type="f/tree">` named
56
+ * after the slot) that the browser rebuilds inside the island, instead of keeping its HTML.
57
+ */
58
+ declare const SLOT_TREE_FIELD = "t";
44
59
  /** `{"$":"a","v":id}` or `{"$":"a","v":id,"b":sealed}`: a server action. */
45
60
  declare const ACTION_TAG = "a";
46
61
  /**
@@ -105,4 +120,4 @@ declare const MAX_HELD_VALUES = 128;
105
120
  * `{"$":"a","v":id,"b":sealed}`), or undefined for anything else.
106
121
  */
107
122
  declare function getTag(value: unknown): string | undefined;
108
- export { VALUES_HEADER as A, RENDER_HEADER as C, TAG_BOUND as D, TAG as E, getTag as F, readPostedAction as I, stripRuntimeFields as L, VALUE_SCRIPT_TYPE as M, attachmentField as N, TAG_VALUE as O, formFieldName as P, REFERENCE_TAG as S, SLOT_TAG as T, MAX_HELD_VALUES as _, BLOB_TAG as a, PROMISE_TAG as b, CHUNK_SCRIPT_TYPE as c, FORM_REF_PREFIX as d, FORM_STATE_SCRIPT_TYPE as f, LAYOUTS_HEADER as g, ISLAND_ELEMENT as h, ACTION_TAG as i, VALUE_KEY_PATTERN as j, TREE_SCRIPT_TYPE as k, FORM_DATA_TAG as l, HYDRATED_ATTRIBUTE as m, ACTION_KEY_FIELD as n, BOUND_FIELD as o, HTML_ELEMENT as p, ACTION_STALE_HEADER as r, CALL_FIELD as s, ACTION_HEADER as t, FORM_FIELD_PREFIX as u, OBJECT_TAG as v, SLOT_ELEMENT as w, PROPS_SCRIPT_TYPE as x, PROMISE_SCRIPT_TYPE as y };
123
+ export { TAG_BOUND as A, stripRuntimeFields as B, REFERENCE_TAG as C, SLOT_TEMPLATE_ELEMENT as D, SLOT_TAG as E, VALUE_SCRIPT_TYPE as F, attachmentField as I, formFieldName as L, TREE_SCRIPT_TYPE as M, VALUES_HEADER as N, SLOT_TREE_FIELD as O, VALUE_KEY_PATTERN as P, getTag as R, PROPS_SCRIPT_TYPE as S, SLOT_ELEMENT as T, LAYOUTS_HEADER as _, BLOB_TAG as a, PROMISE_SCRIPT_TYPE as b, CHUNK_SCRIPT_TYPE as c, FORM_REF_PREFIX as d, FORM_STATE_SCRIPT_TYPE as f, ISLAND_ELEMENT as g, ID_POSITION_ATTRIBUTE as h, ACTION_TAG as i, TAG_VALUE as j, TAG as k, FORM_DATA_TAG as l, HYDRATED_ATTRIBUTE as m, ACTION_KEY_FIELD as n, BOUND_FIELD as o, HTML_ELEMENT as p, ACTION_STALE_HEADER as r, CALL_FIELD as s, ACTION_HEADER as t, FORM_FIELD_PREFIX as u, MAX_HELD_VALUES as v, RENDER_HEADER as w, PROMISE_TAG as x, OBJECT_TAG as y, readPostedAction as z };
@@ -13,12 +13,22 @@
13
13
  const ISLAND_ELEMENT = "f-island";
14
14
  /** The script type of an island's props; its `for` attribute names the island. */
15
15
  const PROPS_SCRIPT_TYPE = "f/props";
16
+ /**
17
+ * On a props script: the id React gave the island's position on the server, so the browser
18
+ * hydrates the island where the server rendered it and `useId` matches.
19
+ */
20
+ const ID_POSITION_ATTRIBUTE = "ids";
16
21
  /** The script type of a value sent once; its `name` attribute is the value's key. */
17
22
  const VALUE_SCRIPT_TYPE = "f/value";
18
23
  /** Set on an island once it hydrated (and its held interaction was replayed). */
19
24
  const HYDRATED_ATTRIBUTE = "hydrated";
20
25
  /** The element that keeps server output passed to an island as children. */
21
26
  const SLOT_ELEMENT = "f-slot";
27
+ /**
28
+ * After an island's props: `<template for>` holding the `<f-slot>`s the island did not place when
29
+ * the server rendered it, which the browser shows when the island places them.
30
+ */
31
+ const SLOT_TEMPLATE_ELEMENT = "template";
22
32
  /** The script type of a page's server tree, rebuilt in the browser without the page's HTML. */
23
33
  const TREE_SCRIPT_TYPE = "f/tree";
24
34
  /** The script type of a server tree chunk that streamed in after the tree. */
@@ -42,6 +52,11 @@ const TAG_BOUND = "b";
42
52
  const REFERENCE_TAG = "r";
43
53
  /** `{"$":"s","v":name}`: a slot. */
44
54
  const SLOT_TAG = "s";
55
+ /**
56
+ * On a slot reference: `1` when the slot carries a server tree (`<script type="f/tree">` named
57
+ * after the slot) that the browser rebuilds inside the island, instead of keeping its HTML.
58
+ */
59
+ const SLOT_TREE_FIELD = "t";
45
60
  /** `{"$":"a","v":id}` or `{"$":"a","v":id,"b":sealed}`: a server action. */
46
61
  const ACTION_TAG = "a";
47
62
  /**
@@ -127,5 +142,6 @@ function getTag(value) {
127
142
  if (keys.length === 1) return tag;
128
143
  if (keys.length === 2 && "v" in value) return tag;
129
144
  if (keys.length === 3 && tag === "a" && "v" in value && "b" in value) return tag;
145
+ if (keys.length === 3 && tag === "s" && "v" in value && "t" in value) return tag;
130
146
  }
131
- export { VALUES_HEADER as A, RENDER_HEADER as C, TAG_BOUND as D, TAG as E, getTag as F, readPostedAction as I, stripRuntimeFields as L, VALUE_SCRIPT_TYPE as M, attachmentField as N, TAG_VALUE as O, formFieldName as P, REFERENCE_TAG as S, SLOT_TAG as T, MAX_HELD_VALUES as _, BLOB_TAG as a, PROMISE_TAG as b, CHUNK_SCRIPT_TYPE as c, FORM_REF_PREFIX as d, FORM_STATE_SCRIPT_TYPE as f, LAYOUTS_HEADER as g, ISLAND_ELEMENT as h, ACTION_TAG as i, VALUE_KEY_PATTERN as j, TREE_SCRIPT_TYPE as k, FORM_DATA_TAG as l, HYDRATED_ATTRIBUTE as m, ACTION_KEY_FIELD as n, BOUND_FIELD as o, HTML_ELEMENT as p, ACTION_STALE_HEADER as r, CALL_FIELD as s, ACTION_HEADER as t, FORM_FIELD_PREFIX as u, OBJECT_TAG as v, SLOT_ELEMENT as w, PROPS_SCRIPT_TYPE as x, PROMISE_SCRIPT_TYPE as y };
147
+ export { TAG_BOUND as A, stripRuntimeFields as B, REFERENCE_TAG as C, SLOT_TEMPLATE_ELEMENT as D, SLOT_TAG as E, VALUE_SCRIPT_TYPE as F, attachmentField as I, formFieldName as L, TREE_SCRIPT_TYPE as M, VALUES_HEADER as N, SLOT_TREE_FIELD as O, VALUE_KEY_PATTERN as P, getTag as R, PROPS_SCRIPT_TYPE as S, SLOT_ELEMENT as T, LAYOUTS_HEADER as _, BLOB_TAG as a, PROMISE_SCRIPT_TYPE as b, CHUNK_SCRIPT_TYPE as c, FORM_REF_PREFIX as d, FORM_STATE_SCRIPT_TYPE as f, ISLAND_ELEMENT as g, ID_POSITION_ATTRIBUTE as h, ACTION_TAG as i, TAG_VALUE as j, TAG as k, FORM_DATA_TAG as l, HYDRATED_ATTRIBUTE as m, ACTION_KEY_FIELD as n, BOUND_FIELD as o, HTML_ELEMENT as p, ACTION_STALE_HEADER as r, CALL_FIELD as s, ACTION_HEADER as t, FORM_FIELD_PREFIX as u, MAX_HELD_VALUES as v, RENDER_HEADER as w, PROMISE_TAG as x, OBJECT_TAG as y, readPostedAction as z };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @farm.js/islx/boot: the first script of a page, in place of the browser entry. It loads the entry
3
+ * (the runtime: the renderer, islx's hydration, navigation and forms) when the page first needs
4
+ * it, so a page whose islands all wait loads only this script until one is used:
5
+ *
6
+ * - at once, when an island hydrates at load (`strategy="load"`, also one that streams in later)
7
+ * or a Suspense boundary is left for the browser to finish;
8
+ * - otherwise on the first island trigger (`idle`; `visible`, with the scheduler's 200px margin;
9
+ * an interaction the inline pre-hydration script saw) or on intent to follow a link (a pointer
10
+ * over it, a press, a focus), or a focus in a form.
11
+ *
12
+ * The inline pre-hydration script holds the clicks and submits on waiting islands until then. A
13
+ * same-site link clicked before the entry has run is held too, and clicked again once it has, so
14
+ * navigation decides as for any click; if the entry fails to load, the link navigates natively.
15
+ *
16
+ * Renderer-neutral, and it imports nothing: a module it shared with the entry would change how the
17
+ * entry splits into chunks. The server names the entry in `window.__islxRuntime`.
18
+ */
19
+ /** Kept equal to the island element (protocol/wire.ts); a test compares them. */
20
+ declare const BOOT_ISLAND_ELEMENT = "f-island";
21
+ /** Kept equal to HYDRATED_ATTRIBUTE (protocol/wire.ts). */
22
+ declare const BOOT_HYDRATED_ATTRIBUTE = "hydrated";
23
+ /** Kept equal to INTERACTION_EVENT (client/prehydration.ts). */
24
+ declare const BOOT_INTERACTION_EVENT = "f:island-interaction";
25
+ /** Kept equal to the scheduler's visibility margin (client/schedule.ts). */
26
+ declare const BOOT_VISIBLE_MARGIN = "200px";
27
+ /** Where the server names the browser entry for the boot. */
28
+ declare const RUNTIME_GLOBAL = "__islxRuntime";
29
+ /** Starts the runtime when the page first needs it. `load` runs it; it starts as it runs. */
30
+ declare function startBoot(load?: () => Promise<unknown>): void;
31
+ export { BOOT_HYDRATED_ATTRIBUTE, BOOT_INTERACTION_EVENT, BOOT_ISLAND_ELEMENT, BOOT_VISIBLE_MARGIN, RUNTIME_GLOBAL, startBoot };
package/dist/boot.mjs ADDED
@@ -0,0 +1,177 @@
1
+ // src/boot.ts
2
+ /**
3
+ * @farm.js/islx/boot: the first script of a page, in place of the browser entry. It loads the entry
4
+ * (the runtime: the renderer, islx's hydration, navigation and forms) when the page first needs
5
+ * it, so a page whose islands all wait loads only this script until one is used:
6
+ *
7
+ * - at once, when an island hydrates at load (`strategy="load"`, also one that streams in later)
8
+ * or a Suspense boundary is left for the browser to finish;
9
+ * - otherwise on the first island trigger (`idle`; `visible`, with the scheduler's 200px margin;
10
+ * an interaction the inline pre-hydration script saw) or on intent to follow a link (a pointer
11
+ * over it, a press, a focus), or a focus in a form.
12
+ *
13
+ * The inline pre-hydration script holds the clicks and submits on waiting islands until then. A
14
+ * same-site link clicked before the entry has run is held too, and clicked again once it has, so
15
+ * navigation decides as for any click; if the entry fails to load, the link navigates natively.
16
+ *
17
+ * Renderer-neutral, and it imports nothing: a module it shared with the entry would change how the
18
+ * entry splits into chunks. The server names the entry in `window.__islxRuntime`.
19
+ */
20
+ /** Kept equal to the island element (protocol/wire.ts); a test compares them. */
21
+ const BOOT_ISLAND_ELEMENT = "f-island";
22
+ /** Kept equal to HYDRATED_ATTRIBUTE (protocol/wire.ts). */
23
+ const BOOT_HYDRATED_ATTRIBUTE = "hydrated";
24
+ /** Kept equal to INTERACTION_EVENT (client/prehydration.ts). */
25
+ const BOOT_INTERACTION_EVENT = "f:island-interaction";
26
+ /** Kept equal to the scheduler's visibility margin (client/schedule.ts). */
27
+ const BOOT_VISIBLE_MARGIN = "200px";
28
+ /** Where the server names the browser entry for the boot. */
29
+ const RUNTIME_GLOBAL = "__islxRuntime";
30
+ function isModified(event) {
31
+ return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey;
32
+ }
33
+ /** A link islx navigation takes: the same checks as its click handler. */
34
+ function navigableLink(target) {
35
+ const link = target instanceof Element ? target.closest("a[href]") : null;
36
+ if (!(link instanceof HTMLAnchorElement)) return null;
37
+ if (link.target && link.target !== "_self") return null;
38
+ if (link.hasAttribute("download") || link.relList.contains("external")) return null;
39
+ const url = new URL(link.href);
40
+ if (url.origin !== location.origin || !/^https?:$/.test(url.protocol)) return null;
41
+ if (url.pathname === location.pathname && url.search === location.search && url.hash) return null;
42
+ return link;
43
+ }
44
+ /** Runs the browser entry the server named, as a module script: the same URL, so the same module. */
45
+ function loadRuntime() {
46
+ const src = window[RUNTIME_GLOBAL];
47
+ if (typeof src !== "string" || src === "") return Promise.reject(/* @__PURE__ */ new Error(`islx: the page names no browser entry (${RUNTIME_GLOBAL}).`));
48
+ return new Promise((resolve, reject) => {
49
+ const script = document.createElement("script");
50
+ script.type = "module";
51
+ script.src = src;
52
+ const nonce = document.querySelector("script[nonce]")?.nonce;
53
+ if (nonce) script.nonce = nonce;
54
+ script.addEventListener("load", () => resolve(), { once: true });
55
+ script.addEventListener("error", () => reject(/* @__PURE__ */ new Error(`islx: ${src} failed to load.`)), { once: true });
56
+ document.head.append(script);
57
+ });
58
+ }
59
+ /** Starts the runtime when the page first needs it. `load` runs it; it starts as it runs. */
60
+ function startBoot(load = loadRuntime) {
61
+ const cleanups = [];
62
+ let loading;
63
+ const release = () => {
64
+ for (const cleanup of cleanups.splice(0)) cleanup();
65
+ };
66
+ const start = () => {
67
+ if (!loading) {
68
+ loading = load().then(release, (error) => {
69
+ release();
70
+ throw error;
71
+ });
72
+ loading.catch((error) => console.error(error));
73
+ }
74
+ return loading;
75
+ };
76
+ const listen = (type, handler, capture) => {
77
+ document.addEventListener(type, handler, capture);
78
+ cleanups.push(() => document.removeEventListener(type, handler, capture));
79
+ };
80
+ listen(BOOT_INTERACTION_EVENT, () => void start(), false);
81
+ const intent = (event) => {
82
+ if (navigableLink(event.target)) start();
83
+ else if (event.type !== "mouseover" && event.target?.closest?.("form")) start();
84
+ };
85
+ for (const type of [
86
+ "pointerdown",
87
+ "focusin",
88
+ "mouseover"
89
+ ]) listen(type, intent, true);
90
+ listen("click", (event) => {
91
+ const click = event;
92
+ if (click.defaultPrevented || click.button !== 0 || isModified(click)) return;
93
+ const link = navigableLink(click.target);
94
+ if (!link) return;
95
+ click.preventDefault();
96
+ start().then(() => {
97
+ if (link.isConnected) link.dispatchEvent(new MouseEvent("click", {
98
+ bubbles: true,
99
+ cancelable: true
100
+ }));
101
+ else location.assign(link.href);
102
+ }, () => location.assign(link.href));
103
+ }, false);
104
+ const visibility = typeof IntersectionObserver === "function" ? new IntersectionObserver((entries) => {
105
+ if (entries.some((entry) => entry.isIntersecting)) start();
106
+ }, { rootMargin: BOOT_VISIBLE_MARGIN }) : null;
107
+ if (visibility) cleanups.push(() => visibility.disconnect());
108
+ let idle = false;
109
+ const startWhenIdle = () => {
110
+ if (idle) return;
111
+ idle = true;
112
+ const scope = window;
113
+ if (typeof scope.requestIdleCallback === "function") {
114
+ const handle = scope.requestIdleCallback(() => void start(), { timeout: 2e3 });
115
+ cleanups.push(() => scope.cancelIdleCallback?.(handle));
116
+ } else {
117
+ const handle = window.setTimeout(() => void start(), 1);
118
+ cleanups.push(() => window.clearTimeout(handle));
119
+ }
120
+ };
121
+ const parsedVisible = [];
122
+ const observeVisible = (island) => {
123
+ const targets = island.getClientRects().length > 0 ? [island] : Array.from(island.children);
124
+ if (!visibility || targets.length === 0) start();
125
+ else for (const target of targets) visibility.observe(target);
126
+ };
127
+ const considerIsland = (island) => {
128
+ if (island.hasAttribute("hydrated")) return;
129
+ if (island.parentElement?.closest("f-island")) return;
130
+ const strategy = island.getAttribute("strategy");
131
+ if (strategy === "interaction") return;
132
+ if (strategy === "idle") startWhenIdle();
133
+ else if (strategy !== "visible") start();
134
+ else if (document.readyState === "loading") parsedVisible.push(island);
135
+ else observeVisible(island);
136
+ };
137
+ const consider = (node) => {
138
+ if (loading) return;
139
+ if (node.nodeType === Node.COMMENT_NODE) {
140
+ if (node.data === "$!") start();
141
+ } else if (node instanceof Element) {
142
+ if (node.matches("f-island")) considerIsland(node);
143
+ for (const island of Array.from(node.querySelectorAll(BOOT_ISLAND_ELEMENT))) considerIsland(island);
144
+ }
145
+ };
146
+ const pendingBoundary = () => {
147
+ const walker = document.createTreeWalker(document, NodeFilter.SHOW_COMMENT);
148
+ while (walker.nextNode()) if (walker.currentNode.data === "$?") return true;
149
+ return false;
150
+ };
151
+ const walker = document.createTreeWalker(document, NodeFilter.SHOW_COMMENT);
152
+ while (!loading && walker.nextNode()) consider(walker.currentNode);
153
+ consider(document.documentElement);
154
+ const parsed = () => {
155
+ if (pendingBoundary()) start();
156
+ for (const island of parsedVisible.splice(0)) if (!loading) observeVisible(island);
157
+ };
158
+ if (!loading && document.readyState === "loading") {
159
+ const observer = new MutationObserver((records) => {
160
+ for (const record of records) for (const node of Array.from(record.addedNodes)) consider(node);
161
+ });
162
+ observer.observe(document, {
163
+ childList: true,
164
+ subtree: true
165
+ });
166
+ const done = () => {
167
+ observer.disconnect();
168
+ parsed();
169
+ };
170
+ document.addEventListener("DOMContentLoaded", done, { once: true });
171
+ cleanups.push(() => {
172
+ observer.disconnect();
173
+ document.removeEventListener("DOMContentLoaded", done);
174
+ });
175
+ } else if (!loading) parsed();
176
+ }
177
+ export { BOOT_HYDRATED_ATTRIBUTE, BOOT_INTERACTION_EVENT, BOOT_ISLAND_ELEMENT, BOOT_VISIBLE_MARGIN, RUNTIME_GLOBAL, startBoot };
package/dist/client.d.mts CHANGED
@@ -57,7 +57,8 @@ declare function startNavigation(options: NavigationOptions): {
57
57
  declare function navigate(href: string, options?: NavigateOptions): Promise<void>;
58
58
  /**
59
59
  * Holding interactions that happen before the islx script has run. An inline script in the page
60
- * captures a click or a submit on an island that has not hydrated (it is prevented and queued),
60
+ * captures a click or a submit on an island that has not hydrated (it is prevented and queued; a
61
+ * click on a link only when the link stays on the page, `#…`),
61
62
  * and announces a pointerdown or a focus (which go through). The runtime then hydrates those
62
63
  * islands first and replays what was held.
63
64
  *
package/dist/client.mjs CHANGED
@@ -1,31 +1,7 @@
1
- import { a as defineClientHooks, c as setClientHooks, d as valueHeaders, i as setActionNavigator, l as createValueStore, n as decodeActionReference, o as emit, r as setActionInterceptor, s as hookEventName, t as createServerReference, u as getValueStore } from "./_chunks/actions-C-IwUCKU.mjs";
2
- import { C as RENDER_HEADER, I as readPostedAction, L as stripRuntimeFields } from "./_chunks/wire-QEQWBr5s.mjs";
3
- import { i as REPLAYABLE_SELECTOR, n as PENDING_INTERACTIONS, r as PREHYDRATION_SCRIPT, t as INTERACTION_EVENT } from "./_chunks/prehydration-B1GLTLdk.mjs";
4
- // src/client/forms.ts
5
- /**
6
- * Forms written in server components submit without reloading the page once JavaScript runs.
7
- * No island owns them, so nothing else would: a submit of a form that posts an action is sent as
8
- * a call, and the page refreshes as after any action, keeping island state. Forms inside islands
9
- * are React's, which handles them first.
10
- */
11
- let enhanced = false;
12
- /** Starts handling server-component forms on this page. Safe to call more than once. */
13
- function enhanceForms() {
14
- if (enhanced) return;
15
- enhanced = true;
16
- document.addEventListener("submit", (event) => {
17
- if (event.defaultPrevented || !(event.target instanceof HTMLFormElement)) return;
18
- const form = event.target;
19
- const submitter = event.submitter ?? null;
20
- const data = new FormData(form, submitter);
21
- const posted = readPostedAction(data);
22
- if (!posted) return;
23
- event.preventDefault();
24
- stripRuntimeFields(data);
25
- form.setAttribute("aria-busy", "true");
26
- createServerReference(posted.id, posted.token)(data).then(() => form.reset()).catch((error) => console.error("[islx] The form's action failed:", error)).finally(() => form.removeAttribute("aria-busy"));
27
- });
28
- }
1
+ import { a as defineClientHooks, c as setClientHooks, d as valueHeaders, i as setActionNavigator, l as createValueStore, n as decodeActionReference, o as emit, r as setActionInterceptor, s as hookEventName, t as createServerReference, u as getValueStore } from "./_chunks/actions-DAzd4PpV.mjs";
2
+ import { n as enhanceForms } from "./_chunks/forms-CCDY9QHC.mjs";
3
+ import { w as RENDER_HEADER } from "./_chunks/wire-UUwZlUJZ.mjs";
4
+ import { i as REPLAYABLE_SELECTOR, n as PENDING_INTERACTIONS, r as PREHYDRATION_SCRIPT, t as INTERACTION_EVENT } from "./_chunks/prehydration-zEYsfFxW.mjs";
29
5
  // src/client/navigation.ts
30
6
  /**
31
7
  * Moving between pages without loading a new document. A click on a same-site link fetches the
@@ -1,2 +1,36 @@
1
1
  import { a as getActionId, i as TransformActionsResult, n as AstNode, o as hasModuleDirective, r as TransformActionsOptions, s as transformActions, t as ActionCompileError } from "./_chunks/actions-BCtIGvrP.mjs";
2
- export { ActionCompileError, type AstNode, type TransformActionsOptions, type TransformActionsResult, getActionId, hasModuleDirective, transformActions };
2
+ import MagicString from "magic-string";
3
+
4
+ // src/compiler/infer.d.ts
5
+ interface InferOptions {
6
+ /** Parses a module's source (TypeScript and JSX included) to an ESTree program. */
7
+ parse(file: string, code: string): AstNode;
8
+ /**
9
+ * Resolves an import to a source file of the app's own, or null for a package or anything
10
+ * unknown (which keeps `"load"`). Default: relative and root-absolute paths, with the usual
11
+ * extensions and index files.
12
+ */
13
+ resolve?(specifier: string, importer: string): string | null;
14
+ }
15
+ interface Inference {
16
+ /** `"interaction"` when the islands can wait; null to keep `"load"`. */
17
+ strategy: "interaction" | null;
18
+ /** The source files the result read, the module itself first. */
19
+ files: string[];
20
+ /** Why the islands keep `"load"`. */
21
+ reason?: string;
22
+ }
23
+ /** Infers when the islands `file` exports hydrate; `code` is its source. */
24
+ declare function inferStrategy(file: string, code: string, options: InferOptions): Inference;
25
+ /** The rewrite for a framework's own transform: the module's new code and map, or null. */
26
+ declare function rewriteFormStatusImports(options: {
27
+ code: string;
28
+ id: string;
29
+ parse(code: string): AstNode;
30
+ /** The module islx's React entry resolves as. Default `@farm.js/islx/react`. */
31
+ from?: string;
32
+ }): {
33
+ code: string;
34
+ map: ReturnType<MagicString["generateMap"]>;
35
+ } | null;
36
+ export { ActionCompileError, type AstNode, type InferOptions, type Inference, type TransformActionsOptions, type TransformActionsResult, getActionId, hasModuleDirective, inferStrategy, rewriteFormStatusImports, transformActions };
package/dist/compiler.mjs CHANGED
@@ -1 +1 @@
1
- export { t as ActionCompileError, n as getActionId, r as hasModuleDirective, i as transformActions } from "./_chunks/actions-Eutk6UzT.mjs";
1
+ export { i as ActionCompileError, a as getActionId, o as hasModuleDirective, r as inferStrategy, n as rewriteFormStatusImports, s as transformActions } from "./_chunks/form-status-CRfnB7WT.mjs";
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { A as VALUES_HEADER, C as RENDER_HEADER, D as TAG_BOUND, E as TAG, F as getTag, I as readPostedAction, L as stripRuntimeFields, M as VALUE_SCRIPT_TYPE, N as attachmentField, O as TAG_VALUE, P as formFieldName, S as REFERENCE_TAG, T as SLOT_TAG, _ as MAX_HELD_VALUES, a as BLOB_TAG, b as PROMISE_TAG, c as CHUNK_SCRIPT_TYPE, d as FORM_REF_PREFIX, f as FORM_STATE_SCRIPT_TYPE, g as LAYOUTS_HEADER, h as ISLAND_ELEMENT, i as ACTION_TAG, j as VALUE_KEY_PATTERN, k as TREE_SCRIPT_TYPE, l as FORM_DATA_TAG, m as HYDRATED_ATTRIBUTE, n as ACTION_KEY_FIELD, o as BOUND_FIELD, p as HTML_ELEMENT, r as ACTION_STALE_HEADER, s as CALL_FIELD, t as ACTION_HEADER, u as FORM_FIELD_PREFIX, v as OBJECT_TAG, w as SLOT_ELEMENT, x as PROPS_SCRIPT_TYPE, y as PROMISE_SCRIPT_TYPE } from "./_chunks/wire-Dipqh-EB.mjs";
1
+ import { A as TAG_BOUND, B as stripRuntimeFields, C as REFERENCE_TAG, D as SLOT_TEMPLATE_ELEMENT, E as SLOT_TAG, F as VALUE_SCRIPT_TYPE, I as attachmentField, L as formFieldName, M as TREE_SCRIPT_TYPE, N as VALUES_HEADER, O as SLOT_TREE_FIELD, P as VALUE_KEY_PATTERN, R as getTag, S as PROPS_SCRIPT_TYPE, T as SLOT_ELEMENT, _ as LAYOUTS_HEADER, a as BLOB_TAG, b as PROMISE_SCRIPT_TYPE, c as CHUNK_SCRIPT_TYPE, d as FORM_REF_PREFIX, f as FORM_STATE_SCRIPT_TYPE, g as ISLAND_ELEMENT, h as ID_POSITION_ATTRIBUTE, i as ACTION_TAG, j as TAG_VALUE, k as TAG, l as FORM_DATA_TAG, m as HYDRATED_ATTRIBUTE, n as ACTION_KEY_FIELD, o as BOUND_FIELD, p as HTML_ELEMENT, r as ACTION_STALE_HEADER, s as CALL_FIELD, t as ACTION_HEADER, u as FORM_FIELD_PREFIX, v as MAX_HELD_VALUES, w as RENDER_HEADER, x as PROMISE_TAG, y as OBJECT_TAG, z as readPostedAction } from "./_chunks/wire-1d6wqOia.mjs";
2
2
  import { a as decode, c as encodeLeaf, d as plainObject, f as tagged, i as NOT_A_VALUE, l as fromBase64, n as EncodeError, o as decodeTagged, p as toBase64, r as EncodeOptions, s as encode, t as DecodeOptions, u as needsObjectTag } from "./_chunks/codec-CK8kZp4u.mjs";
3
- export { ACTION_HEADER, ACTION_KEY_FIELD, ACTION_STALE_HEADER, ACTION_TAG, BLOB_TAG, BOUND_FIELD, CALL_FIELD, CHUNK_SCRIPT_TYPE, type DecodeOptions, EncodeError, type EncodeOptions, FORM_DATA_TAG, FORM_FIELD_PREFIX, FORM_REF_PREFIX, FORM_STATE_SCRIPT_TYPE, HTML_ELEMENT, HYDRATED_ATTRIBUTE, ISLAND_ELEMENT, LAYOUTS_HEADER, MAX_HELD_VALUES, NOT_A_VALUE, OBJECT_TAG, PROMISE_SCRIPT_TYPE, PROMISE_TAG, PROPS_SCRIPT_TYPE, REFERENCE_TAG, RENDER_HEADER, SLOT_ELEMENT, SLOT_TAG, TAG, TAG_BOUND, TAG_VALUE, TREE_SCRIPT_TYPE, VALUES_HEADER, VALUE_KEY_PATTERN, VALUE_SCRIPT_TYPE, attachmentField, decode, decodeTagged, encode, encodeLeaf, formFieldName, fromBase64, getTag, needsObjectTag, plainObject, readPostedAction, stripRuntimeFields, tagged, toBase64 };
3
+ export { ACTION_HEADER, ACTION_KEY_FIELD, ACTION_STALE_HEADER, ACTION_TAG, BLOB_TAG, BOUND_FIELD, CALL_FIELD, CHUNK_SCRIPT_TYPE, type DecodeOptions, EncodeError, type EncodeOptions, FORM_DATA_TAG, FORM_FIELD_PREFIX, FORM_REF_PREFIX, FORM_STATE_SCRIPT_TYPE, HTML_ELEMENT, HYDRATED_ATTRIBUTE, ID_POSITION_ATTRIBUTE, ISLAND_ELEMENT, LAYOUTS_HEADER, MAX_HELD_VALUES, NOT_A_VALUE, OBJECT_TAG, PROMISE_SCRIPT_TYPE, PROMISE_TAG, PROPS_SCRIPT_TYPE, REFERENCE_TAG, RENDER_HEADER, SLOT_ELEMENT, SLOT_TAG, SLOT_TEMPLATE_ELEMENT, SLOT_TREE_FIELD, TAG, TAG_BOUND, TAG_VALUE, TREE_SCRIPT_TYPE, VALUES_HEADER, VALUE_KEY_PATTERN, VALUE_SCRIPT_TYPE, attachmentField, decode, decodeTagged, encode, encodeLeaf, formFieldName, fromBase64, getTag, needsObjectTag, plainObject, readPostedAction, stripRuntimeFields, tagged, toBase64 };
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { A as VALUES_HEADER, C as RENDER_HEADER, D as TAG_BOUND, E as TAG, F as getTag, I as readPostedAction, L as stripRuntimeFields, M as VALUE_SCRIPT_TYPE, N as attachmentField, O as TAG_VALUE, P as formFieldName, S as REFERENCE_TAG, T as SLOT_TAG, _ as MAX_HELD_VALUES, a as BLOB_TAG, b as PROMISE_TAG, c as CHUNK_SCRIPT_TYPE, d as FORM_REF_PREFIX, f as FORM_STATE_SCRIPT_TYPE, g as LAYOUTS_HEADER, h as ISLAND_ELEMENT, i as ACTION_TAG, j as VALUE_KEY_PATTERN, k as TREE_SCRIPT_TYPE, l as FORM_DATA_TAG, m as HYDRATED_ATTRIBUTE, n as ACTION_KEY_FIELD, o as BOUND_FIELD, p as HTML_ELEMENT, r as ACTION_STALE_HEADER, s as CALL_FIELD, t as ACTION_HEADER, u as FORM_FIELD_PREFIX, v as OBJECT_TAG, w as SLOT_ELEMENT, x as PROPS_SCRIPT_TYPE, y as PROMISE_SCRIPT_TYPE } from "./_chunks/wire-QEQWBr5s.mjs";
2
- import { a as encode, c as needsObjectTag, d as tagged, f as toBase64, i as decodeTagged, l as plainObject, n as NOT_A_VALUE, o as encodeLeaf, r as decode, s as fromBase64, t as EncodeError } from "./_chunks/codec-C8to-RQW.mjs";
3
- export { ACTION_HEADER, ACTION_KEY_FIELD, ACTION_STALE_HEADER, ACTION_TAG, BLOB_TAG, BOUND_FIELD, CALL_FIELD, CHUNK_SCRIPT_TYPE, EncodeError, FORM_DATA_TAG, FORM_FIELD_PREFIX, FORM_REF_PREFIX, FORM_STATE_SCRIPT_TYPE, HTML_ELEMENT, HYDRATED_ATTRIBUTE, ISLAND_ELEMENT, LAYOUTS_HEADER, MAX_HELD_VALUES, NOT_A_VALUE, OBJECT_TAG, PROMISE_SCRIPT_TYPE, PROMISE_TAG, PROPS_SCRIPT_TYPE, REFERENCE_TAG, RENDER_HEADER, SLOT_ELEMENT, SLOT_TAG, TAG, TAG_BOUND, TAG_VALUE, TREE_SCRIPT_TYPE, VALUES_HEADER, VALUE_KEY_PATTERN, VALUE_SCRIPT_TYPE, attachmentField, decode, decodeTagged, encode, encodeLeaf, formFieldName, fromBase64, getTag, needsObjectTag, plainObject, readPostedAction, stripRuntimeFields, tagged, toBase64 };
1
+ import { A as TAG_BOUND, B as stripRuntimeFields, C as REFERENCE_TAG, D as SLOT_TEMPLATE_ELEMENT, E as SLOT_TAG, F as VALUE_SCRIPT_TYPE, I as attachmentField, L as formFieldName, M as TREE_SCRIPT_TYPE, N as VALUES_HEADER, O as SLOT_TREE_FIELD, P as VALUE_KEY_PATTERN, R as getTag, S as PROPS_SCRIPT_TYPE, T as SLOT_ELEMENT, _ as LAYOUTS_HEADER, a as BLOB_TAG, b as PROMISE_SCRIPT_TYPE, c as CHUNK_SCRIPT_TYPE, d as FORM_REF_PREFIX, f as FORM_STATE_SCRIPT_TYPE, g as ISLAND_ELEMENT, h as ID_POSITION_ATTRIBUTE, i as ACTION_TAG, j as TAG_VALUE, k as TAG, l as FORM_DATA_TAG, m as HYDRATED_ATTRIBUTE, n as ACTION_KEY_FIELD, o as BOUND_FIELD, p as HTML_ELEMENT, r as ACTION_STALE_HEADER, s as CALL_FIELD, t as ACTION_HEADER, u as FORM_FIELD_PREFIX, v as MAX_HELD_VALUES, w as RENDER_HEADER, x as PROMISE_TAG, y as OBJECT_TAG, z as readPostedAction } from "./_chunks/wire-UUwZlUJZ.mjs";
2
+ import { a as encode, c as needsObjectTag, d as tagged, f as toBase64, i as decodeTagged, l as plainObject, n as NOT_A_VALUE, o as encodeLeaf, r as decode, s as fromBase64, t as EncodeError } from "./_chunks/codec-DDpUvgRo.mjs";
3
+ export { ACTION_HEADER, ACTION_KEY_FIELD, ACTION_STALE_HEADER, ACTION_TAG, BLOB_TAG, BOUND_FIELD, CALL_FIELD, CHUNK_SCRIPT_TYPE, EncodeError, FORM_DATA_TAG, FORM_FIELD_PREFIX, FORM_REF_PREFIX, FORM_STATE_SCRIPT_TYPE, HTML_ELEMENT, HYDRATED_ATTRIBUTE, ID_POSITION_ATTRIBUTE, ISLAND_ELEMENT, LAYOUTS_HEADER, MAX_HELD_VALUES, NOT_A_VALUE, OBJECT_TAG, PROMISE_SCRIPT_TYPE, PROMISE_TAG, PROPS_SCRIPT_TYPE, REFERENCE_TAG, RENDER_HEADER, SLOT_ELEMENT, SLOT_TAG, SLOT_TEMPLATE_ELEMENT, SLOT_TREE_FIELD, TAG, TAG_BOUND, TAG_VALUE, TREE_SCRIPT_TYPE, VALUES_HEADER, VALUE_KEY_PATTERN, VALUE_SCRIPT_TYPE, attachmentField, decode, decodeTagged, encode, encodeLeaf, formFieldName, fromBase64, getTag, needsObjectTag, plainObject, readPostedAction, stripRuntimeFields, tagged, toBase64 };
@@ -1,7 +1,7 @@
1
1
  import { a as scheduleHydration, i as isIslandStrategy, n as IslandStrategy, r as ScheduleOptions, t as ISLAND_STRATEGIES } from "../_chunks/schedule-Dw14dW0H.mjs";
2
- import { m as HYDRATED_ATTRIBUTE } from "../_chunks/wire-Dipqh-EB.mjs";
2
+ import { m as HYDRATED_ATTRIBUTE } from "../_chunks/wire-1d6wqOia.mjs";
3
3
  import { t as ValueStore } from "../_chunks/value-store-Dm-7xJ6W.mjs";
4
- import { a as ServerTreeLayoutOptions, c as createServerTreeLayout, g as isolateIslands, i as ServerTreeLayout, n as PAYLOAD_ONLY_ATTRIBUTE, r as ServerTreeElementOptions, s as createServerTreeElement, u as updateServerTrees, v as withinClientRoot } from "../_chunks/tree-B4RMU2UX.mjs";
4
+ import { a as ServerTreeLayoutOptions, c as createServerTreeLayout, g as isolateIslands, i as ServerTreeLayout, n as PAYLOAD_ONLY_ATTRIBUTE, r as ServerTreeElementOptions, s as createServerTreeElement, u as updateServerTrees, v as withinClientRoot } from "../_chunks/tree-CV13RsJv.mjs";
5
5
  import * as React from "react";
6
6
 
7
7
  // src/react/hydrate.d.ts