@backtickjs/bundler 0.1.7 → 0.1.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.
package/README.md CHANGED
@@ -16,10 +16,14 @@ For React Native, write CommonJS and serve it; the app fetches it and runs it wi
16
16
  import { bundler } from "@backtickjs/bundler";
17
17
  import { Home } from "./Home.js";
18
18
 
19
- const packageVersions = { react: "19.2.3", "react-native": "0.86.3" };
19
+ const modules = {
20
+ react: "19.2.3",
21
+ "react/jsx-runtime": "19.2.3",
22
+ "react-native": "0.86.3",
23
+ };
20
24
 
21
25
  // In a request handler:
22
- const bundle = await bundler.build({ input: <Home />, packageVersions });
26
+ const bundle = await bundler.build({ input: <Home />, modules });
23
27
  const { code } = bundle.generate({ format: "cjs" });
24
28
  response.setHeader("content-type", "text/javascript");
25
29
  response.end(code);
@@ -36,14 +40,20 @@ import { Home } from "./Home.js";
36
40
  const element = <Home />;
37
41
  const bundle = await bundler.build({
38
42
  input: cs`$createRoot(document.getElementById("app")!).render($element)`,
39
- packageVersions: { react: "19.2.3", "react-dom": "19.2.3" },
43
+ modules: {
44
+ react: "19.2.3",
45
+ "react/jsx-runtime": "19.2.3",
46
+ "react-dom/client": "19.2.3",
47
+ },
40
48
  });
41
49
  const { code } = bundle.generate({ format: "es", sourcemap: "inline" });
42
50
  ```
43
51
 
44
- ### `packageVersions`
52
+ ### `modules`
45
53
 
46
- The packages the client provides, each at its exact version. The server decides which versions to bundle for: one app version, or one per client if your server tells them apart. Those packages are left out of the bundle, which imports (`es`) or requires (`cjs`) them. `build` rejects a script that imports from any other package, or whose import needs a range that doesn't include the version given: an adapter's (`^19.2.3` for `@backtickjs/react`) or one written with `createImport`.
54
+ The modules the client provides, by specifier, each at the exact version of the package it comes from: `"react-dom/client": "19.2.3"`. The server decides which to bundle for: one app version, or one per build with [`@backtickjs/builds`](https://github.com/backtickjs/backtick/tree/main/packages/builds). Those modules are left out of the bundle, which imports (`es`) or requires (`cjs`) them. `build` rejects a script that imports from any other module, or whose import needs a range that doesn't include the version given: an adapter's (`^19.2.3` for `@backtickjs/react`) or one written with `createImport`.
55
+
56
+ `supports(modules, specifier, range)` makes the same check, for a server choosing what to draw for a client: `supports(modules, "expo-haptics", "^15")`.
47
57
 
48
58
  ### What crosses into a script
49
59
 
@@ -60,7 +70,7 @@ Spliced values are written into the bundle as data, never as code. What can't cr
60
70
 
61
71
  ## API
62
72
 
63
- - `bundler.build({ input, packageVersions })`: runs the server components in `input` and returns a `Bundle`. Async.
73
+ - `bundler.build({ input, modules })`: runs the server components in `input` and returns a `Bundle`. Async.
64
74
  - `Bundle.generate({ format, sourcemap })`: writes the bundle; returns `{ code, map }`, where `map` is `null` without a source map.
65
75
  - Types: `BuildOptions`, `OutputOptions`, `OutputChunk`, `Bundle`.
66
76
 
@@ -68,7 +78,7 @@ Spliced values are written into the bundle as data, never as code. What can't cr
68
78
 
69
79
  - [`@backtickjs/core`](https://github.com/backtickjs/backtick/tree/main/packages/core): the `cs` tag
70
80
  - [`@backtickjs/react-native-client`](https://github.com/backtickjs/backtick/tree/main/packages/react-native-client): runs a `cjs` bundle in a React Native app
71
- - [`@backtickjs/react`](https://github.com/backtickjs/backtick/tree/main/packages/react), [`@backtickjs/react-native`](https://github.com/backtickjs/backtick/tree/main/packages/react-native), [`@backtickjs/solid-js`](https://github.com/backtickjs/backtick/tree/main/packages/solid-js): framework adapters
81
+ - [`@backtickjs/react`](https://github.com/backtickjs/backtick/tree/main/adapters/react), [`@backtickjs/react-native`](https://github.com/backtickjs/backtick/tree/main/adapters/react-native), [`@backtickjs/solid-js`](https://github.com/backtickjs/backtick/tree/main/adapters/solid-js): framework adapters
72
82
  - [How it works](https://backtickjs.com/docs/how-it-works)
73
83
  - [Errors](https://backtickjs.com/docs/errors)
74
84
 
@@ -1,5 +1,6 @@
1
1
  import { type ClientModule } from "@backtickjs/core";
2
2
  import type { Names } from "../print/code.js";
3
+ import type { Modules } from "../modules.js";
3
4
  /**
4
5
  * A bundle as it is built, before it is printed: each script's module it
5
6
  * declares under its label, in the order rendering first reached it, and the
@@ -11,4 +12,4 @@ export interface BundleTree {
11
12
  readonly root: string;
12
13
  readonly names: Names;
13
14
  }
14
- export declare function buildBundle(value: unknown, packageVersions: Readonly<Record<string, string>>): Promise<BundleTree>;
15
+ export declare function buildBundle(value: unknown, provided: Modules): Promise<BundleTree>;
@@ -1,5 +1,5 @@
1
1
  import { isClientImport, isClientScript, isJsxElement, } from "@backtickjs/core";
2
- import { expandJsxElement } from "./expandJsxElement.js";
2
+ import { expandServerComponents } from "./expandServerComponents.js";
3
3
  import { bindingsOf, capturesOf } from "./params.js";
4
4
  import { sourceName } from "./bindingKey.js";
5
5
  import { array, arrow, call, createNames, imported, literal, object, } from "../print/code.js";
@@ -25,8 +25,8 @@ const rootScope = () => ({ bindings: new Set(), read: new Set() });
25
25
  // name, a capture is threaded under that one name the whole way down — an
26
26
  // intermediate script that binds a same-looking variable has a different
27
27
  // unique name, so there is nothing to disambiguate and nothing to rename.
28
- export async function buildBundle(value, packageVersions) {
29
- const names = createNames(packageVersions);
28
+ export async function buildBundle(value, provided) {
29
+ const names = createNames(provided);
30
30
  // Each script's number, in the order rendering first reaches it. Two
31
31
  // scripts written at one source location are one declaration, so the first
32
32
  // script with an id stands for all of them, and a reference to a shared
@@ -100,9 +100,9 @@ export async function buildBundle(value, packageVersions) {
100
100
  // `write` renders a closure's code in a scope that records what it reads:
101
101
  // a constant's label if it read nothing of `scope` beyond `own`, its
102
102
  // parameters, or else the code, written where it's used.
103
- const closure = async (scope, own, write, name) => {
103
+ const closure = (scope, own, write, name) => {
104
104
  const read = new Set();
105
- const code = await write({
105
+ const code = write({
106
106
  bindings: new Set([...scope.bindings, ...own]),
107
107
  read,
108
108
  });
@@ -119,42 +119,41 @@ export async function buildBundle(value, packageVersions) {
119
119
  }
120
120
  return label;
121
121
  };
122
+ // A `once` script is one value: its code run at the top of the bundle,
123
+ // where nothing encloses it, and every read is that constant. One per
124
+ // script, which is one per call of `once`, not per code: two runs of a host
125
+ // function that each make a context are two contexts, as two calls of
126
+ // `createContext` are. Running code is observable, so unlike a function it
127
+ // is never shared by code.
128
+ const values = new Map();
129
+ const valueOf = (script) => {
130
+ let label = values.get(script);
131
+ if (label === undefined) {
132
+ const code = call(labelOf(scriptFor(script)), exprCallArgs(script, rootScope()));
133
+ label = `$value${constants.length}`;
134
+ values.set(script, label);
135
+ constants.push([label, code]);
136
+ }
137
+ return label;
138
+ };
122
139
  // Writes a value as the code it becomes: composition as data, which is what
123
140
  // a bundle is. A script reference is a call naming which script and
124
141
  // what to hand it; everything else is its literal form. Rendered in order,
125
142
  // one value after the other, so the table follows the order rendering first
126
- // reached each script.
127
- // The objects rendering is inside of now. One it meets again contains
128
- // itself, which written out would never end. A value used in two places
129
- // isn't one: it's left before it's met again.
130
- const path = new Set();
131
- const render = async (value, scope = rootScope()) => {
132
- if (typeof value !== "object" || value === null) {
133
- return renderValue(value, scope);
134
- }
135
- if (path.has(value)) {
136
- throw new Error("Can't splice a value that contains itself: a bundle writes each " +
137
- "value out in full, so a cycle never ends. Break the cycle before " +
138
- "splicing it.");
139
- }
140
- path.add(value);
141
- try {
142
- return await renderValue(value, scope);
143
- }
144
- finally {
145
- path.delete(value);
146
- }
147
- };
148
- const renderValue = async (value, scope) => {
143
+ // reached each script. Expansion has refused cycles, so it ends.
144
+ const render = (value, scope = rootScope()) => {
149
145
  if (isClientScript(value)) {
146
+ if (value.once) {
147
+ return valueOf(value);
148
+ }
150
149
  const target = scriptFor(value);
151
150
  if (target.module.kind !== "function") {
152
- return call(labelOf(target), await exprCallArgs(value, scope));
151
+ return call(labelOf(target), exprCallArgs(value, scope));
153
152
  }
154
- return closure(scope, [], async (inner) => call(labelOf(target), await exprCallArgs(value, inner)), "$function");
153
+ return closure(scope, [], (inner) => call(labelOf(target), exprCallArgs(value, inner)), "$function");
155
154
  }
156
155
  if (isJsxElement(value)) {
157
- return renderJsx(value, scope);
156
+ return renderJsx(value);
158
157
  }
159
158
  if (isClientImport(value)) {
160
159
  return imported(names, value);
@@ -170,7 +169,7 @@ export async function buildBundle(value, packageVersions) {
170
169
  if (Array.isArray(value)) {
171
170
  const elements = [];
172
171
  for (const element of value) {
173
- elements.push(await render(element, scope));
172
+ elements.push(render(element, scope));
174
173
  }
175
174
  return array(elements);
176
175
  }
@@ -205,7 +204,7 @@ export async function buildBundle(value, packageVersions) {
205
204
  }
206
205
  const entries = [];
207
206
  for (const [key, entry] of Object.entries(value)) {
208
- entries.push([key, await render(entry, scope)]);
207
+ entries.push([key, render(entry, scope)]);
209
208
  }
210
209
  return object(entries);
211
210
  };
@@ -224,11 +223,13 @@ export async function buildBundle(value, packageVersions) {
224
223
  sourceName(key) +
225
224
  "` shadows it: the binding is still there, but no longer reachable by " +
226
225
  "name, and naming it anyway would mean emitting what the source " +
227
- "couldn't say.");
226
+ "couldn't say. A `once` script is made at the top of the bundle, " +
227
+ "outside every script, so a fragment spliced into one can't reach " +
228
+ "its binding either.");
228
229
  };
229
230
  // The arguments of a call of a script: a thunk per splice, then its
230
231
  // captures.
231
- const exprCallArgs = async (ref, scope) => {
232
+ const exprCallArgs = (ref, scope) => {
232
233
  const target = scriptFor(ref);
233
234
  const parts = [];
234
235
  // The splices lead the parameters, one `arg` each.
@@ -238,25 +239,17 @@ export async function buildBundle(value, packageVersions) {
238
239
  // nested inside it.
239
240
  const passed = [...passKeys(target, index), ...capturesOf(target)];
240
241
  // A thunk taking them, the splice rendered inside it.
241
- parts.push(await closure(scope, passed, async (inner) => arrow(passed.map(displayName), await render(arg, inner)), "$thunk"));
242
+ parts.push(closure(scope, passed, (inner) => arrow(passed.map(displayName), render(arg, inner)), "$thunk"));
242
243
  }
243
244
  for (const key of capturesOf(target)) {
244
245
  parts.push(capExpr(key, scope));
245
246
  }
246
247
  return parts;
247
248
  };
248
- // A tag. A component runs on the host and what it drew stands where the tag
249
- // stood; an element is its own name, each prop an expression in the
250
- // enclosing script's scope.
251
- //
252
- // A prop that is `undefined` is left out, as JSX and TypeScript's optional
253
- // props read it: a component forwarding an optional prop it wasn't given
254
- // writes nothing.
255
- const renderJsx = async (jsx, scope) => {
249
+ // A tag left after expansion, which ran every server component's: one the
250
+ // client draws.
251
+ const renderJsx = (jsx) => {
256
252
  const type = jsx.type;
257
- if (typeof type === "function" && !isClientImport(type)) {
258
- return render(await expandJsxElement(jsx, type), scope);
259
- }
260
253
  // An element and a client component (an import, or a script answering
261
254
  // one) are client code, so on the host they can't be tags: they are tags
262
255
  // in a script.
@@ -268,8 +261,9 @@ export async function buildBundle(value, packageVersions) {
268
261
  throw new Error(`${tag} is a client component, so it can't be a tag on the host. ` +
269
262
  "Use it as a tag in a script.");
270
263
  };
271
- // Nothing encloses the root, so nothing it holds can capture.
272
- const root = await render(value);
264
+ // Every server component first, so siblings run at once; then the drawing,
265
+ // in order. Nothing encloses the root, so nothing it holds can capture.
266
+ const root = render(await expandServerComponents(value));
273
267
  // In table order, which is the order rendering first reached each script.
274
268
  const modules = [...numbers.keys()].map((script) => [labelOf(script), script.module]);
275
269
  return { modules, constants, root, names };
@@ -1 +1 @@
1
- {"version":3,"file":"buildBundle.js","sourceRoot":"","sources":["../../src/bundle/buildBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EACd,cAAc,EACd,YAAY,GAEb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,OAAO,EACP,MAAM,GACP,MAAM,kBAAkB,CAAC;AAiB1B,6EAA6E;AAC7E,4EAA4E;AAC5E,4BAA4B;AAC5B,MAAM,QAAQ,GAAG,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAUzD,MAAM,SAAS,GAAG,GAAU,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;AAE1E,+DAA+D;AAC/D,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,wEAAwE;AACxE,wEAAwE;AACxE,8EAA8E;AAC9E,WAAW;AACX,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,0EAA0E;AAC1E,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAc,EACd,eAAiD;IAEjD,MAAM,KAAK,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;IAC3C,qEAAqE;IACrE,2EAA2E;IAC3E,wEAAwE;IACxE,4EAA4E;IAC5E,yEAAyE;IACzE,mCAAmC;IACnC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAChD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAwB,CAAC;IACnD,MAAM,SAAS,GAAG,CAAC,MAAoB,EAAgB,EAAE;QACvD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IACF,8EAA8E;IAC9E,oDAAoD;IACpD,EAAE;IACF,+EAA+E;IAC/E,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,uEAAuE;IACvE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,oCAAoC;IACpC,EAAE;IACF,yEAAyE;IACzE,yEAAyE;IACzE,2EAA2E;IAC3E,2EAA2E;IAC3E,yBAAyB;IACzB,EAAE;IACF,6EAA6E;IAC7E,qEAAqE;IACrE,4EAA4E;IAC5E,wDAAwD;IACxD,MAAM,QAAQ,GAAG,CAAC,MAAoB,EAAE,IAAY,EAAqB,EAAE,CACzE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzC,0CAA0C;IAC1C,MAAM,OAAO,GAAG,CAAC,MAAoB,EAAU,EAAE,CAC/C,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,EAAE,CAAC;IAE/B,4EAA4E;IAC5E,wEAAwE;IACxE,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,4EAA4E;IAC5E,qEAAqE;IACrE,wEAAwE;IACxE,kCAAkC;IAClC,MAAM,SAAS,GAAkC,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,0EAA0E;IAC1E,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,OAAO,GAAG,KAAK,EACnB,KAAY,EACZ,GAAsB,EACtB,KAAwC,EACxC,IAAY,EACK,EAAE;QACnB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC;YACvB,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC;YAC9C,IAAI;SACL,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CACvD,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,GAAG,GAAG,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACxB,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,4EAA4E;IAC5E,oEAAoE;IACpE,2EAA2E;IAC3E,4EAA4E;IAC5E,uBAAuB;IACvB,sEAAsE;IACtE,wEAAwE;IACxE,8CAA8C;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,KAAK,EAClB,KAAc,EACd,QAAe,SAAS,EAAE,EACT,EAAE;QACnB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAChD,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,kEAAkE;gBAChE,mEAAmE;gBACnE,cAAc,CACjB,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,EAAE,KAAc,EAAE,KAAY,EAAmB,EAAE;QAC1E,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACtC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,OAAO,CACZ,KAAK,EACL,EAAE,EACF,KAAK,EAAE,KAAK,EAAE,EAAE,CACd,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EACzD,WAAW,CACZ,CAAC;QACJ,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,IACE,KAAK,KAAK,IAAI;YACd,KAAK,KAAK,SAAS;YACnB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;YACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QACD,uEAAuE;QACvE,2DAA2D;QAC3D,gEAAgE;QAChE,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,CAAC,IAAI,KAAK,EAAE;gBACV,CAAC,CAAC,8BAA8B;gBAChC,CAAC,CAAC,oCAAoC,IAAI,IAAI,CAAC;gBAC/C,8DAA8D;gBAC9D,kEAAkE;gBAClE,2DAA2D;gBAC3D,UAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,UAAU,CAC1D,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,mEAAmE;gBACjE,qEAAqE;gBACrE,oCAAoC,CACvC,CAAC;QACJ,CAAC;QACD,0EAA0E;QAC1E,uEAAuE;QACvE,0EAA0E;QAC1E,0EAA0E;QAC1E,SAAS;QACT,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,IAAI,kBAAkB,CAAC;YAC3D,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,6CAA6C;gBACtE,4DAA4D,CAC/D,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAuB,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,6EAA6E;IAC7E,4EAA4E;IAC5E,mCAAmC;IACnC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,KAAY,EAAU,EAAE;QACpD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,8BAA8B,UAAU,CAAC,GAAG,CAAC,uBAAuB;YAClE,sEAAsE;YACtE,kEAAkE;YAClE,qBAAqB;YACrB,UAAU,CAAC,GAAG,CAAC;YACf,uEAAuE;YACvE,iEAAiE;YACjE,eAAe,CAClB,CAAC;IACJ,CAAC,CAAC;IAEF,oEAAoE;IACpE,YAAY;IACZ,MAAM,YAAY,GAAG,KAAK,EACxB,GAAiB,EACjB,KAAY,EACO,EAAE;QACrB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,mDAAmD;QACnD,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9C,wEAAwE;YACxE,sEAAsE;YACtE,oBAAoB;YACpB,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YACnE,sDAAsD;YACtD,KAAK,CAAC,IAAI,CACR,MAAM,OAAO,CACX,KAAK,EACL,MAAM,EACN,KAAK,EAAE,KAAK,EAAE,EAAE,CACd,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAC1D,QAAQ,CACT,CACF,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,4EAA4E;IAC5E,oEAAoE;IACpE,4BAA4B;IAC5B,EAAE;IACF,2EAA2E;IAC3E,yEAAyE;IACzE,kBAAkB;IAClB,MAAM,SAAS,GAAG,KAAK,EAAE,GAAe,EAAE,KAAY,EAAmB,EAAE;QACzE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,OAAO,MAAM,CAAC,MAAM,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC;QACD,sEAAsE;QACtE,yEAAyE;QACzE,eAAe;QACf,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,MAAM,IAAI,yDAAyD;gBACjE,QAAQ,IAAI,OAAO,IAAI,MAAM,CAChC,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,GAAG,GAAG,4DAA4D;YAChE,8BAA8B,CACjC,CAAC;IACJ,CAAC,CAAC;IAEF,8DAA8D;IAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,0EAA0E;IAC1E,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CACrC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAU,CACtD,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"buildBundle.js","sourceRoot":"","sources":["../../src/bundle/buildBundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type ClientScript } from "@backtickjs/core";
2
+ interface Ancestors {
3
+ readonly value: object;
4
+ readonly parent: Ancestors | null;
5
+ }
6
+ export declare function expandServerComponents(value: unknown, ancestors?: Ancestors | null, values?: Map<ClientScript, Promise<unknown>>): Promise<unknown>;
7
+ export {};
@@ -0,0 +1,77 @@
1
+ import { isClientImport, isClientScript, isJsxElement, } from "@backtickjs/core";
2
+ const CYCLE_ERROR = "Can't splice a value that contains itself: a bundle writes each value " +
3
+ "out in full, so a cycle never ends. Break the cycle before splicing it.";
4
+ const contains = (ancestors, value) => {
5
+ for (let at = ancestors; at !== null; at = at.parent) {
6
+ if (at.value === value) {
7
+ return true;
8
+ }
9
+ }
10
+ return false;
11
+ };
12
+ // Runs every server component in a value and answers with the value as drawn:
13
+ // each element of one replaced by what its component drew, expanded in turn.
14
+ // Siblings expand at once, so two components awaiting data wait together.
15
+ //
16
+ // A component runs each time its element is drawn, as React renders an element
17
+ // each place it stands: the component itself never leaves the host, and only
18
+ // the client code it bottoms out in reaches the bundle. A value holding no
19
+ // server component comes back as the same object.
20
+ //
21
+ // A `once` script is one value, so what it splices is expanded once, however
22
+ // many places read it: a server component inside it runs once. `values` holds
23
+ // each one's expansion for the call.
24
+ export async function expandServerComponents(value, ancestors = null, values = new Map()) {
25
+ if (typeof value !== "object" || value === null) {
26
+ return value;
27
+ }
28
+ if (contains(ancestors, value)) {
29
+ throw new Error(CYCLE_ERROR);
30
+ }
31
+ const inside = { value, parent: ancestors };
32
+ const all = (entries) => Promise.all(entries.map((entry) => expandServerComponents(entry, inside, values)));
33
+ if (isJsxElement(value)) {
34
+ const { type } = value;
35
+ // A tag the client draws is left for rendering to refuse.
36
+ if (typeof type !== "function" || isClientImport(type)) {
37
+ return value;
38
+ }
39
+ return expandServerComponents(await type(value.props), inside, values);
40
+ }
41
+ if (isClientScript(value)) {
42
+ const expanded = async () => {
43
+ const args = await all(value.args);
44
+ return args.every((arg, index) => arg === value.args[index])
45
+ ? value
46
+ : { ...value, args };
47
+ };
48
+ if (!value.once) {
49
+ return expanded();
50
+ }
51
+ let made = values.get(value);
52
+ if (made === undefined) {
53
+ made = expanded();
54
+ values.set(value, made);
55
+ }
56
+ return made;
57
+ }
58
+ if (Array.isArray(value)) {
59
+ const elements = await all(value);
60
+ return elements.every((element, index) => element === value[index])
61
+ ? value
62
+ : elements;
63
+ }
64
+ // Only plain objects cross; rendering refuses anything else.
65
+ const prototype = Object.getPrototypeOf(value);
66
+ if (prototype !== Object.prototype && prototype !== null) {
67
+ return value;
68
+ }
69
+ const entries = Object.entries(value);
70
+ const expanded = await all(entries.map(([, entry]) => entry));
71
+ if (expanded.every((entry, index) => entry === entries[index][1])) {
72
+ return value;
73
+ }
74
+ // Defined, not assigned, so a `__proto__` key stays a key.
75
+ return Object.fromEntries(entries.map(([key], index) => [key, expanded[index]]));
76
+ }
77
+ //# sourceMappingURL=expandServerComponents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expandServerComponents.js","sourceRoot":"","sources":["../../src/bundle/expandServerComponents.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,cAAc,EACd,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,GACf,wEAAwE;IACxE,yEAAyE,CAAC;AAS5E,MAAM,QAAQ,GAAG,CAAC,SAA2B,EAAE,KAAa,EAAW,EAAE;IACvE,KAAK,IAAI,EAAE,GAAG,SAAS,EAAE,EAAE,KAAK,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;QACrD,IAAI,EAAE,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,2EAA2E;AAC3E,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAc,EACd,YAA8B,IAAI,EAClC,SAAS,IAAI,GAAG,EAAkC;IAElD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,MAAM,GAAc,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACvD,MAAM,GAAG,GAAG,CAAC,OAA2B,EAAE,EAAE,CAC1C,OAAO,CAAC,GAAG,CACT,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CACtE,CAAC;IAEJ,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QACvB,0DAA0D;QAC1D,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,sBAAsB,CAC3B,MAAM,IAAI,CAAC,KAAK,CAAC,KAAc,CAAC,EAChC,MAAM,EACN,MAAM,CACP,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,KAAK,IAAsB,EAAE;YAC5C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1D,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAChB,OAAO,QAAQ,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,GAAG,QAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC;YACjE,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,QAAQ,CAAC;IACf,CAAC;IACD,6DAA6D;IAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,2DAA2D;IAC3D,OAAO,MAAM,CAAC,WAAW,CACvB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CACtD,CAAC;AACJ,CAAC"}
package/dist/bundler.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import type { Spliceable, SplicesAs } from "@backtickjs/core";
2
+ import type { Modules } from "./modules.js";
2
3
  export interface BuildOptions<T = Spliceable> {
3
4
  readonly input: T;
4
- readonly packageVersions: Readonly<Record<string, string>>;
5
+ readonly modules: Modules;
5
6
  }
6
7
  export interface OutputOptions {
7
8
  readonly format: "es" | "cjs";
@@ -20,7 +21,7 @@ export interface Bundle {
20
21
  * What runs your components and hands back what they drew, shaped as Rollup
21
22
  * is: a build, then output from it.
22
23
  *
23
- * const bundle = await bundler.build({ input: <Home />, packageVersions });
24
+ * const bundle = await bundler.build({ input: <Home />, modules });
24
25
  * const { code, map } = bundle.generate({ format: "es", sourcemap: "hidden" });
25
26
  *
26
27
  * The module's default export is the value (CommonJS: `module.exports`). A
@@ -28,5 +29,5 @@ export interface Bundle {
28
29
  * give what comes back.
29
30
  */
30
31
  export declare const bundler: {
31
- build<T extends [T] extends [SplicesAs<T>] ? unknown : Spliceable>({ input, packageVersions, }: BuildOptions<T>): Promise<Bundle>;
32
+ build<T extends [T] extends [SplicesAs<T>] ? unknown : Spliceable>({ input, modules, }: BuildOptions<T>): Promise<Bundle>;
32
33
  };
package/dist/bundler.js CHANGED
@@ -4,7 +4,7 @@ import { printBundle } from "./print/printBundle.js";
4
4
  * What runs your components and hands back what they drew, shaped as Rollup
5
5
  * is: a build, then output from it.
6
6
  *
7
- * const bundle = await bundler.build({ input: <Home />, packageVersions });
7
+ * const bundle = await bundler.build({ input: <Home />, modules });
8
8
  * const { code, map } = bundle.generate({ format: "es", sourcemap: "hidden" });
9
9
  *
10
10
  * The module's default export is the value (CommonJS: `module.exports`). A
@@ -12,10 +12,10 @@ import { printBundle } from "./print/printBundle.js";
12
12
  * give what comes back.
13
13
  */
14
14
  export const bundler = {
15
- async build({ input, packageVersions, }) {
15
+ async build({ input, modules, }) {
16
16
  // Scripts come compiled for their framework when their host was built, so
17
17
  // the bundle is only put together: nothing is compiled or parsed here.
18
- const tree = await buildBundle(input, packageVersions);
18
+ const tree = await buildBundle(input, modules);
19
19
  return {
20
20
  generate: ({ format, sourcemap = false }) => {
21
21
  const { code, map } = printBundle(tree, format);
@@ -1 +1 @@
1
- {"version":3,"file":"bundler.js","sourceRoot":"","sources":["../src/bundler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAiCrD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,KAAK,CAAC,KAAK,CAA8D,EACvE,KAAK,EACL,eAAe,GACC;QAChB,0EAA0E;QAC1E,uEAAuE;QACvE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACvD,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,EAAE,EAAE;gBAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAChD,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;oBACxB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;gBAC7B,CAAC;gBACD,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC3B,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;gBACvB,CAAC;gBACD,MAAM,GAAG,GAAG,uCAAuC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7E,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,0BAA0B,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC;YAC/D,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"bundler.js","sourceRoot":"","sources":["../src/bundler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAiCrD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,KAAK,CAAC,KAAK,CAA8D,EACvE,KAAK,EACL,OAAO,GACS;QAChB,0EAA0E;QAC1E,uEAAuE;QACvE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,EAAE,EAAE;gBAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAChD,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;oBACxB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;gBAC7B,CAAC;gBACD,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC3B,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;gBACvB,CAAC;gBACD,MAAM,GAAG,GAAG,uCAAuC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7E,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,0BAA0B,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC;YAC/D,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { type Bundle, type BuildOptions, bundler, type OutputChunk, type OutputOptions, } from "./bundler.js";
2
+ export { type Modules, supports } from "./modules.js";
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { bundler, } from "./bundler.js";
2
+ export { supports } from "./modules.js";
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,OAAO,GAGR,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,OAAO,GAGR,MAAM,cAAc,CAAC;AACtB,OAAO,EAAgB,QAAQ,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The modules a client provides, by specifier, each at the exact version of
3
+ * the package it comes from: `{ "react/jsx-runtime": "19.2.3" }`.
4
+ */
5
+ export type Modules = Readonly<Record<string, string>>;
6
+ /**
7
+ * Whether a client with `modules` provides `specifier` at a version in
8
+ * `range`: the check a bundle's every import passes, so a server choosing
9
+ * what to draw for a client can ask it first.
10
+ */
11
+ export declare function supports(modules: Modules, specifier: string, range: string): boolean;
@@ -0,0 +1,11 @@
1
+ import semver from "semver";
2
+ /**
3
+ * Whether a client with `modules` provides `specifier` at a version in
4
+ * `range`: the check a bundle's every import passes, so a server choosing
5
+ * what to draw for a client can ask it first.
6
+ */
7
+ export function supports(modules, specifier, range) {
8
+ const provided = modules[specifier];
9
+ return provided !== undefined && semver.satisfies(provided, range);
10
+ }
11
+ //# sourceMappingURL=modules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAQ5B;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAgB,EAChB,SAAiB,EACjB,KAAa;IAEb,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACpC,OAAO,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AACrE,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import type { ClientImport } from "@backtickjs/core";
2
+ import { type Modules } from "../modules.js";
2
3
  /**
3
4
  * What a bundle imports, keyed by specifier and export, each bound once; and
4
- * the packages it may import them from, which the client provides, by version.
5
+ * the modules it may import them from, which the client provides, by version.
5
6
  */
6
7
  export interface Names {
7
8
  readonly imports: Map<string, {
@@ -9,9 +10,9 @@ export interface Names {
9
10
  name: string;
10
11
  local: string;
11
12
  }>;
12
- readonly packageVersions: Readonly<Record<string, string>>;
13
+ readonly modules: Modules;
13
14
  }
14
- export declare function createNames(packageVersions: Readonly<Record<string, string>>): Names;
15
+ export declare function createNames(modules: Modules): Names;
15
16
  export declare function string(value: string): string;
16
17
  export declare function literal(value: string | number | bigint | boolean | null | undefined): string;
17
18
  export declare function call(callee: string, args: readonly string[]): string;
@@ -1,10 +1,10 @@
1
- import semver from "semver";
1
+ import { supports } from "../modules.js";
2
2
  // What a bundle is written as, and the one place its conventions live: how a
3
3
  // name is written, how a literal escapes, and how an element is written as JSX
4
4
  // for the framework's compiler. Everything is code, as a string.
5
5
  const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
6
- export function createNames(packageVersions) {
7
- return { imports: new Map(), packageVersions };
6
+ export function createNames(modules) {
7
+ return { imports: new Map(), modules };
8
8
  }
9
9
  // A string, as a literal: `<` escaped, so no `</script>` or `<!--` appears
10
10
  // when the bundle is inlined in a page, and the line and paragraph separators,
@@ -50,26 +50,19 @@ function member(key) {
50
50
  }
51
51
  return IDENTIFIER.test(key) ? key : string(key);
52
52
  }
53
- // The package a module is in: its specifier's first segment, or first two
54
- // when scoped (`solid-js/web` → `solid-js`, `@scope/pkg/x` → `@scope/pkg`).
55
- function packageOf(from) {
56
- const segments = from.split("/");
57
- return segments.slice(0, from.startsWith("@") ? 2 : 1).join("/");
58
- }
59
53
  /** An export of a module the client provides, imported by the bundle. */
60
54
  export function imported(names, { from, name, version }) {
61
55
  // Where a script's import is written: a plugin's own (a framework's compile
62
56
  // step) are the plugin's, trusted as it is.
63
- const pkg = packageOf(from);
64
- const provided = names.packageVersions[pkg];
57
+ const provided = names.modules[from];
65
58
  if (provided === undefined) {
66
- const packages = Object.entries(names.packageVersions).map(([provided, at]) => `${provided}@${at}`);
59
+ const listed = Object.entries(names.modules).map(([specifier, at]) => `${specifier}@${at}`);
67
60
  throw new Error(`Can't import \`${name}\` from "${from}": the client provides ` +
68
- `${packages.join(", ") || "no packages"}.`);
61
+ `${listed.join(", ") || "no modules"}.`);
69
62
  }
70
- if (!semver.satisfies(provided, version)) {
71
- throw new Error(`Can't import \`${name}\` from "${from}": it needs ${pkg}@${version}, ` +
72
- `and the client provides ${pkg}@${provided}.`);
63
+ if (!supports(names.modules, from, version)) {
64
+ throw new Error(`Can't import \`${name}\` from "${from}": it needs ${version}, and ` +
65
+ `the client provides ${from}@${provided}.`);
73
66
  }
74
67
  const key = `${from}\0${name}`;
75
68
  let entry = names.imports.get(key);
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/print/code.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/print/code.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD,6EAA6E;AAC7E,+EAA+E;AAC/E,iEAAiE;AAEjE,MAAM,UAAU,GAAG,4BAA4B,CAAC;AAWhD,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC;AAED,2EAA2E;AAC3E,+EAA+E;AAC/E,qEAAqE;AACrE,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAClC,kBAAkB,EAClB,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACnE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,KAA4D;IAE5D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,iEAAiE;QACjE,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,GAAG,KAAK,GAAG,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,IAAuB;IAC1D,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,6EAA6E;AAC7E,SAAS;AACT,MAAM,UAAU,KAAK,CAAC,MAAyB,EAAE,IAAY;IAC3D,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,QAA2B;IAC/C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACpC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,MAAM,CACpB,OAA+C;IAE/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAC1E,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,+EAA+E;AAC/E,+EAA+E;AAC/E,mCAAmC;AACnC,SAAS,MAAM,CAAC,GAAW;IACzB,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;QACxB,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;IAC5B,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CACtB,KAAY,EACZ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAyB;IAE9C,4EAA4E;IAC5E,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAC9C,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,IAAI,EAAE,EAAE,CAC1C,CAAC;QACF,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,YAAY,IAAI,yBAAyB;YAC7D,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,YAAY,GAAG,CAC1C,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,YAAY,IAAI,eAAe,OAAO,QAAQ;YAClE,uBAAuB,IAAI,IAAI,QAAQ,GAAG,CAC7C,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACzD,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC;AACrB,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,IAAY,EACZ,KAAa;IAEb,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,YAAY,QAAQ,OAAO,KAAK,WAAW,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;AACpE,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,IAAY,EACZ,KAAa;IAEb,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,WAAW,QAAQ,KAAK,KAAK,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AACvE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtickjs/bundler",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Runs Backtick server components and bundles a screen per request: one JavaScript file for the client",
5
5
  "keywords": [
6
6
  "backtick",
@@ -39,8 +39,8 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "semver": "^7.8.1",
43
- "@backtickjs/core": "0.1.7"
42
+ "@backtickjs/core": "^0.1.9",
43
+ "semver": "^7.8.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/semver": "^7.8.0",
@@ -7,7 +7,7 @@ import {
7
7
  type JsxElement,
8
8
  } from "@backtickjs/core";
9
9
 
10
- import { expandJsxElement } from "./expandJsxElement.js";
10
+ import { expandServerComponents } from "./expandServerComponents.js";
11
11
  import { bindingsOf, capturesOf } from "./params.js";
12
12
  import { sourceName } from "./bindingKey.js";
13
13
  import {
@@ -20,6 +20,7 @@ import {
20
20
  object,
21
21
  } from "../print/code.js";
22
22
  import type { Names } from "../print/code.js";
23
+ import type { Modules } from "../modules.js";
23
24
 
24
25
  /**
25
26
  * A bundle as it is built, before it is printed: each script's module it
@@ -28,8 +29,8 @@ import type { Names } from "../print/code.js";
28
29
  */
29
30
  export interface BundleTree {
30
31
  readonly modules: readonly (readonly [string, ClientModule])[];
31
- // The functions the bundle makes once, each under its label, in the order
32
- // they're finished: after what they read.
32
+ // The functions and `once` values the bundle makes once, each under its
33
+ // label, in the order they're finished: after what they read.
33
34
  readonly constants: readonly (readonly [string, string])[];
34
35
  readonly root: string;
35
36
  readonly names: Names;
@@ -69,9 +70,9 @@ const rootScope = (): Scope => ({ bindings: new Set(), read: new Set() });
69
70
  // unique name, so there is nothing to disambiguate and nothing to rename.
70
71
  export async function buildBundle(
71
72
  value: unknown,
72
- packageVersions: Readonly<Record<string, string>>,
73
+ provided: Modules,
73
74
  ): Promise<BundleTree> {
74
- const names = createNames(packageVersions);
75
+ const names = createNames(provided);
75
76
  // Each script's number, in the order rendering first reaches it. Two
76
77
  // scripts written at one source location are one declaration, so the first
77
78
  // script with an id stands for all of them, and a reference to a shared
@@ -150,14 +151,14 @@ export async function buildBundle(
150
151
  // `write` renders a closure's code in a scope that records what it reads:
151
152
  // a constant's label if it read nothing of `scope` beyond `own`, its
152
153
  // parameters, or else the code, written where it's used.
153
- const closure = async (
154
+ const closure = (
154
155
  scope: Scope,
155
156
  own: readonly string[],
156
- write: (inner: Scope) => Promise<string>,
157
+ write: (inner: Scope) => string,
157
158
  name: string,
158
- ): Promise<string> => {
159
+ ): string => {
159
160
  const read = new Set<string>();
160
- const code = await write({
161
+ const code = write({
161
162
  bindings: new Set([...scope.bindings, ...own]),
162
163
  read,
163
164
  });
@@ -177,52 +178,50 @@ export async function buildBundle(
177
178
  return label;
178
179
  };
179
180
 
181
+ // A `once` script is one value: its code run at the top of the bundle,
182
+ // where nothing encloses it, and every read is that constant. One per
183
+ // script, which is one per call of `once`, not per code: two runs of a host
184
+ // function that each make a context are two contexts, as two calls of
185
+ // `createContext` are. Running code is observable, so unlike a function it
186
+ // is never shared by code.
187
+ const values = new Map<ClientScript, string>();
188
+ const valueOf = (script: ClientScript): string => {
189
+ let label = values.get(script);
190
+ if (label === undefined) {
191
+ const code = call(
192
+ labelOf(scriptFor(script)),
193
+ exprCallArgs(script, rootScope()),
194
+ );
195
+ label = `$value${constants.length}`;
196
+ values.set(script, label);
197
+ constants.push([label, code]);
198
+ }
199
+ return label;
200
+ };
201
+
180
202
  // Writes a value as the code it becomes: composition as data, which is what
181
203
  // a bundle is. A script reference is a call naming which script and
182
204
  // what to hand it; everything else is its literal form. Rendered in order,
183
205
  // one value after the other, so the table follows the order rendering first
184
- // reached each script.
185
- // The objects rendering is inside of now. One it meets again contains
186
- // itself, which written out would never end. A value used in two places
187
- // isn't one: it's left before it's met again.
188
- const path = new Set<object>();
189
- const render = async (
190
- value: unknown,
191
- scope: Scope = rootScope(),
192
- ): Promise<string> => {
193
- if (typeof value !== "object" || value === null) {
194
- return renderValue(value, scope);
195
- }
196
- if (path.has(value)) {
197
- throw new Error(
198
- "Can't splice a value that contains itself: a bundle writes each " +
199
- "value out in full, so a cycle never ends. Break the cycle before " +
200
- "splicing it.",
201
- );
202
- }
203
- path.add(value);
204
- try {
205
- return await renderValue(value, scope);
206
- } finally {
207
- path.delete(value);
208
- }
209
- };
210
- const renderValue = async (value: unknown, scope: Scope): Promise<string> => {
206
+ // reached each script. Expansion has refused cycles, so it ends.
207
+ const render = (value: unknown, scope: Scope = rootScope()): string => {
211
208
  if (isClientScript(value)) {
209
+ if (value.once) {
210
+ return valueOf(value);
211
+ }
212
212
  const target = scriptFor(value);
213
213
  if (target.module.kind !== "function") {
214
- return call(labelOf(target), await exprCallArgs(value, scope));
214
+ return call(labelOf(target), exprCallArgs(value, scope));
215
215
  }
216
216
  return closure(
217
217
  scope,
218
218
  [],
219
- async (inner) =>
220
- call(labelOf(target), await exprCallArgs(value, inner)),
219
+ (inner) => call(labelOf(target), exprCallArgs(value, inner)),
221
220
  "$function",
222
221
  );
223
222
  }
224
223
  if (isJsxElement(value)) {
225
- return renderJsx(value, scope);
224
+ return renderJsx(value);
226
225
  }
227
226
  if (isClientImport(value)) {
228
227
  return imported(names, value);
@@ -240,7 +239,7 @@ export async function buildBundle(
240
239
  if (Array.isArray(value)) {
241
240
  const elements: string[] = [];
242
241
  for (const element of value) {
243
- elements.push(await render(element, scope));
242
+ elements.push(render(element, scope));
244
243
  }
245
244
  return array(elements);
246
245
  }
@@ -281,7 +280,7 @@ export async function buildBundle(
281
280
  }
282
281
  const entries: [string, string][] = [];
283
282
  for (const [key, entry] of Object.entries(value)) {
284
- entries.push([key, await render(entry, scope)]);
283
+ entries.push([key, render(entry, scope)]);
285
284
  }
286
285
  return object(entries);
287
286
  };
@@ -302,16 +301,15 @@ export async function buildBundle(
302
301
  sourceName(key) +
303
302
  "` shadows it: the binding is still there, but no longer reachable by " +
304
303
  "name, and naming it anyway would mean emitting what the source " +
305
- "couldn't say.",
304
+ "couldn't say. A `once` script is made at the top of the bundle, " +
305
+ "outside every script, so a fragment spliced into one can't reach " +
306
+ "its binding either.",
306
307
  );
307
308
  };
308
309
 
309
310
  // The arguments of a call of a script: a thunk per splice, then its
310
311
  // captures.
311
- const exprCallArgs = async (
312
- ref: ClientScript,
313
- scope: Scope,
314
- ): Promise<string[]> => {
312
+ const exprCallArgs = (ref: ClientScript, scope: Scope): string[] => {
315
313
  const target = scriptFor(ref);
316
314
  const parts: string[] = [];
317
315
  // The splices lead the parameters, one `arg` each.
@@ -322,11 +320,10 @@ export async function buildBundle(
322
320
  const passed = [...passKeys(target, index), ...capturesOf(target)];
323
321
  // A thunk taking them, the splice rendered inside it.
324
322
  parts.push(
325
- await closure(
323
+ closure(
326
324
  scope,
327
325
  passed,
328
- async (inner) =>
329
- arrow(passed.map(displayName), await render(arg, inner)),
326
+ (inner) => arrow(passed.map(displayName), render(arg, inner)),
330
327
  "$thunk",
331
328
  ),
332
329
  );
@@ -337,18 +334,10 @@ export async function buildBundle(
337
334
  return parts;
338
335
  };
339
336
 
340
- // A tag. A component runs on the host and what it drew stands where the tag
341
- // stood; an element is its own name, each prop an expression in the
342
- // enclosing script's scope.
343
- //
344
- // A prop that is `undefined` is left out, as JSX and TypeScript's optional
345
- // props read it: a component forwarding an optional prop it wasn't given
346
- // writes nothing.
347
- const renderJsx = async (jsx: JsxElement, scope: Scope): Promise<string> => {
337
+ // A tag left after expansion, which ran every server component's: one the
338
+ // client draws.
339
+ const renderJsx = (jsx: JsxElement): never => {
348
340
  const type = jsx.type;
349
- if (typeof type === "function" && !isClientImport(type)) {
350
- return render(await expandJsxElement(jsx, type), scope);
351
- }
352
341
  // An element and a client component (an import, or a script answering
353
342
  // one) are client code, so on the host they can't be tags: they are tags
354
343
  // in a script.
@@ -365,8 +354,9 @@ export async function buildBundle(
365
354
  );
366
355
  };
367
356
 
368
- // Nothing encloses the root, so nothing it holds can capture.
369
- const root = await render(value);
357
+ // Every server component first, so siblings run at once; then the drawing,
358
+ // in order. Nothing encloses the root, so nothing it holds can capture.
359
+ const root = render(await expandServerComponents(value));
370
360
  // In table order, which is the order rendering first reached each script.
371
361
  const modules = [...numbers.keys()].map(
372
362
  (script) => [labelOf(script), script.module] as const,
@@ -0,0 +1,106 @@
1
+ import {
2
+ type ClientScript,
3
+ isClientImport,
4
+ isClientScript,
5
+ isJsxElement,
6
+ } from "@backtickjs/core";
7
+
8
+ const CYCLE_ERROR =
9
+ "Can't splice a value that contains itself: a bundle writes each value " +
10
+ "out in full, so a cycle never ends. Break the cycle before splicing it.";
11
+
12
+ // The objects a value is inside of, innermost first. Each branch has its own,
13
+ // so siblings expanding at once never see each other's.
14
+ interface Ancestors {
15
+ readonly value: object;
16
+ readonly parent: Ancestors | null;
17
+ }
18
+
19
+ const contains = (ancestors: Ancestors | null, value: object): boolean => {
20
+ for (let at = ancestors; at !== null; at = at.parent) {
21
+ if (at.value === value) {
22
+ return true;
23
+ }
24
+ }
25
+ return false;
26
+ };
27
+
28
+ // Runs every server component in a value and answers with the value as drawn:
29
+ // each element of one replaced by what its component drew, expanded in turn.
30
+ // Siblings expand at once, so two components awaiting data wait together.
31
+ //
32
+ // A component runs each time its element is drawn, as React renders an element
33
+ // each place it stands: the component itself never leaves the host, and only
34
+ // the client code it bottoms out in reaches the bundle. A value holding no
35
+ // server component comes back as the same object.
36
+ //
37
+ // A `once` script is one value, so what it splices is expanded once, however
38
+ // many places read it: a server component inside it runs once. `values` holds
39
+ // each one's expansion for the call.
40
+ export async function expandServerComponents(
41
+ value: unknown,
42
+ ancestors: Ancestors | null = null,
43
+ values = new Map<ClientScript, Promise<unknown>>(),
44
+ ): Promise<unknown> {
45
+ if (typeof value !== "object" || value === null) {
46
+ return value;
47
+ }
48
+ if (contains(ancestors, value)) {
49
+ throw new Error(CYCLE_ERROR);
50
+ }
51
+ const inside: Ancestors = { value, parent: ancestors };
52
+ const all = (entries: readonly unknown[]) =>
53
+ Promise.all(
54
+ entries.map((entry) => expandServerComponents(entry, inside, values)),
55
+ );
56
+
57
+ if (isJsxElement(value)) {
58
+ const { type } = value;
59
+ // A tag the client draws is left for rendering to refuse.
60
+ if (typeof type !== "function" || isClientImport(type)) {
61
+ return value;
62
+ }
63
+ return expandServerComponents(
64
+ await type(value.props as never),
65
+ inside,
66
+ values,
67
+ );
68
+ }
69
+ if (isClientScript(value)) {
70
+ const expanded = async (): Promise<unknown> => {
71
+ const args = await all(value.args);
72
+ return args.every((arg, index) => arg === value.args[index])
73
+ ? value
74
+ : { ...value, args };
75
+ };
76
+ if (!value.once) {
77
+ return expanded();
78
+ }
79
+ let made = values.get(value);
80
+ if (made === undefined) {
81
+ made = expanded();
82
+ values.set(value, made);
83
+ }
84
+ return made;
85
+ }
86
+ if (Array.isArray(value)) {
87
+ const elements = await all(value);
88
+ return elements.every((element, index) => element === value[index])
89
+ ? value
90
+ : elements;
91
+ }
92
+ // Only plain objects cross; rendering refuses anything else.
93
+ const prototype = Object.getPrototypeOf(value);
94
+ if (prototype !== Object.prototype && prototype !== null) {
95
+ return value;
96
+ }
97
+ const entries = Object.entries(value);
98
+ const expanded = await all(entries.map(([, entry]) => entry));
99
+ if (expanded.every((entry, index) => entry === entries[index]![1])) {
100
+ return value;
101
+ }
102
+ // Defined, not assigned, so a `__proto__` key stays a key.
103
+ return Object.fromEntries(
104
+ entries.map(([key], index) => [key, expanded[index]]),
105
+ );
106
+ }
package/src/bundler.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import type { Spliceable, SplicesAs } from "@backtickjs/core";
2
2
  import { buildBundle } from "./bundle/buildBundle.js";
3
+ import type { Modules } from "./modules.js";
3
4
  import { printBundle } from "./print/printBundle.js";
4
5
 
5
6
  export interface BuildOptions<T = Spliceable> {
6
7
  // What to bundle: what a splice could carry, checked as a splice checks it.
7
8
  readonly input: T;
8
- // The packages the client provides, each at its exact version: left out of
9
- // the bundle, which requires them. A script's import from any other, or
10
- // needing a version it doesn't have, throws.
11
- readonly packageVersions: Readonly<Record<string, string>>;
9
+ // The modules the client provides, by specifier, each at its package's
10
+ // exact version: left out of the bundle, which requires them. A script's
11
+ // import from any other, or needing a version it doesn't have, throws.
12
+ readonly modules: Modules;
12
13
  }
13
14
 
14
15
  export interface OutputOptions {
@@ -37,7 +38,7 @@ export interface Bundle {
37
38
  * What runs your components and hands back what they drew, shaped as Rollup
38
39
  * is: a build, then output from it.
39
40
  *
40
- * const bundle = await bundler.build({ input: <Home />, packageVersions });
41
+ * const bundle = await bundler.build({ input: <Home />, modules });
41
42
  * const { code, map } = bundle.generate({ format: "es", sourcemap: "hidden" });
42
43
  *
43
44
  * The module's default export is the value (CommonJS: `module.exports`). A
@@ -47,11 +48,11 @@ export interface Bundle {
47
48
  export const bundler = {
48
49
  async build<T extends [T] extends [SplicesAs<T>] ? unknown : Spliceable>({
49
50
  input,
50
- packageVersions,
51
+ modules,
51
52
  }: BuildOptions<T>): Promise<Bundle> {
52
53
  // Scripts come compiled for their framework when their host was built, so
53
54
  // the bundle is only put together: nothing is compiled or parsed here.
54
- const tree = await buildBundle(input, packageVersions);
55
+ const tree = await buildBundle(input, modules);
55
56
  return {
56
57
  generate: ({ format, sourcemap = false }) => {
57
58
  const { code, map } = printBundle(tree, format);
package/src/index.ts CHANGED
@@ -5,3 +5,4 @@ export {
5
5
  type OutputChunk,
6
6
  type OutputOptions,
7
7
  } from "./bundler.js";
8
+ export { type Modules, supports } from "./modules.js";
package/src/modules.ts ADDED
@@ -0,0 +1,21 @@
1
+ import semver from "semver";
2
+
3
+ /**
4
+ * The modules a client provides, by specifier, each at the exact version of
5
+ * the package it comes from: `{ "react/jsx-runtime": "19.2.3" }`.
6
+ */
7
+ export type Modules = Readonly<Record<string, string>>;
8
+
9
+ /**
10
+ * Whether a client with `modules` provides `specifier` at a version in
11
+ * `range`: the check a bundle's every import passes, so a server choosing
12
+ * what to draw for a client can ask it first.
13
+ */
14
+ export function supports(
15
+ modules: Modules,
16
+ specifier: string,
17
+ range: string,
18
+ ): boolean {
19
+ const provided = modules[specifier];
20
+ return provided !== undefined && semver.satisfies(provided, range);
21
+ }
package/src/print/code.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ClientImport } from "@backtickjs/core";
2
- import semver from "semver";
2
+ import { type Modules, supports } from "../modules.js";
3
3
 
4
4
  // What a bundle is written as, and the one place its conventions live: how a
5
5
  // name is written, how a literal escapes, and how an element is written as JSX
@@ -9,17 +9,15 @@ const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
9
9
 
10
10
  /**
11
11
  * What a bundle imports, keyed by specifier and export, each bound once; and
12
- * the packages it may import them from, which the client provides, by version.
12
+ * the modules it may import them from, which the client provides, by version.
13
13
  */
14
14
  export interface Names {
15
15
  readonly imports: Map<string, { from: string; name: string; local: string }>;
16
- readonly packageVersions: Readonly<Record<string, string>>;
16
+ readonly modules: Modules;
17
17
  }
18
18
 
19
- export function createNames(
20
- packageVersions: Readonly<Record<string, string>>,
21
- ): Names {
22
- return { imports: new Map(), packageVersions };
19
+ export function createNames(modules: Modules): Names {
20
+ return { imports: new Map(), modules };
23
21
  }
24
22
 
25
23
  // A string, as a literal: `<` escaped, so no `</script>` or `<!--` appears
@@ -80,13 +78,6 @@ function member(key: string): string {
80
78
  return IDENTIFIER.test(key) ? key : string(key);
81
79
  }
82
80
 
83
- // The package a module is in: its specifier's first segment, or first two
84
- // when scoped (`solid-js/web` → `solid-js`, `@scope/pkg/x` → `@scope/pkg`).
85
- function packageOf(from: string): string {
86
- const segments = from.split("/");
87
- return segments.slice(0, from.startsWith("@") ? 2 : 1).join("/");
88
- }
89
-
90
81
  /** An export of a module the client provides, imported by the bundle. */
91
82
  export function imported(
92
83
  names: Names,
@@ -94,21 +85,20 @@ export function imported(
94
85
  ): string {
95
86
  // Where a script's import is written: a plugin's own (a framework's compile
96
87
  // step) are the plugin's, trusted as it is.
97
- const pkg = packageOf(from);
98
- const provided = names.packageVersions[pkg];
88
+ const provided = names.modules[from];
99
89
  if (provided === undefined) {
100
- const packages = Object.entries(names.packageVersions).map(
101
- ([provided, at]) => `${provided}@${at}`,
90
+ const listed = Object.entries(names.modules).map(
91
+ ([specifier, at]) => `${specifier}@${at}`,
102
92
  );
103
93
  throw new Error(
104
94
  `Can't import \`${name}\` from "${from}": the client provides ` +
105
- `${packages.join(", ") || "no packages"}.`,
95
+ `${listed.join(", ") || "no modules"}.`,
106
96
  );
107
97
  }
108
- if (!semver.satisfies(provided, version)) {
98
+ if (!supports(names.modules, from, version)) {
109
99
  throw new Error(
110
- `Can't import \`${name}\` from "${from}": it needs ${pkg}@${version}, ` +
111
- `and the client provides ${pkg}@${provided}.`,
100
+ `Can't import \`${name}\` from "${from}": it needs ${version}, and ` +
101
+ `the client provides ${from}@${provided}.`,
112
102
  );
113
103
  }
114
104
  const key = `${from}\0${name}`;
@@ -1,2 +0,0 @@
1
- import type { JsxElement } from "@backtickjs/core";
2
- export declare function expandJsxElement(jsx: JsxElement, component: (props: never) => unknown): Promise<unknown>;
@@ -1,8 +0,0 @@
1
- // Runs a host component and answers with what it drew, each time an element
2
- // is drawn, as React renders an element each place it stands. The component
3
- // itself never leaves the host: a server component expands away here, and
4
- // only the client component it bottoms out in reaches the bundle.
5
- export async function expandJsxElement(jsx, component) {
6
- return component(jsx.props);
7
- }
8
- //# sourceMappingURL=expandJsxElement.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"expandJsxElement.js","sourceRoot":"","sources":["../../src/bundle/expandJsxElement.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAe,EACf,SAAoC;IAEpC,OAAO,SAAS,CAAC,GAAG,CAAC,KAAc,CAAC,CAAC;AACvC,CAAC"}
@@ -1,12 +0,0 @@
1
- import type { JsxElement } from "@backtickjs/core";
2
-
3
- // Runs a host component and answers with what it drew, each time an element
4
- // is drawn, as React renders an element each place it stands. The component
5
- // itself never leaves the host: a server component expands away here, and
6
- // only the client component it bottoms out in reaches the bundle.
7
- export async function expandJsxElement(
8
- jsx: JsxElement,
9
- component: (props: never) => unknown,
10
- ): Promise<unknown> {
11
- return component(jsx.props as never);
12
- }