@backtickjs/bundler 0.1.2 → 0.1.3
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/dist/bundle/buildBundle.d.ts +2 -2
- package/dist/bundle/buildBundle.js +60 -76
- package/dist/bundle/buildBundle.js.map +1 -1
- package/dist/bundle/expandJsxElement.d.ts +1 -2
- package/dist/bundle/expandJsxElement.js +6 -11
- package/dist/bundle/expandJsxElement.js.map +1 -1
- package/dist/print/code.d.ts +0 -1
- package/dist/print/code.js +0 -3
- package/dist/print/code.js.map +1 -1
- package/dist/print/printBundle.js +3 -0
- package/dist/print/printBundle.js.map +1 -1
- package/package.json +2 -2
- package/src/bundle/buildBundle.ts +87 -89
- package/src/bundle/expandJsxElement.ts +6 -20
- package/src/print/code.ts +0 -4
- package/src/print/printBundle.ts +3 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { type ClientModule } from "@backtickjs/core";
|
|
2
|
-
import { type Spliceable } from "@backtickjs/core";
|
|
1
|
+
import { type ClientModule, type Spliceable } from "@backtickjs/core";
|
|
3
2
|
import type { Names } from "../print/code.js";
|
|
4
3
|
/**
|
|
5
4
|
* A bundle as it is built, before it is printed: each script's module it
|
|
@@ -8,6 +7,7 @@ import type { Names } from "../print/code.js";
|
|
|
8
7
|
*/
|
|
9
8
|
export interface BundleTree {
|
|
10
9
|
readonly modules: readonly (readonly [string, ClientModule])[];
|
|
10
|
+
readonly constants: readonly (readonly [string, string])[];
|
|
11
11
|
readonly root: string;
|
|
12
12
|
readonly names: Names;
|
|
13
13
|
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import { isClientScript, isJsxElement, } from "@backtickjs/core";
|
|
2
|
-
import {
|
|
3
|
-
import { expandJsxElement, } from "./expandJsxElement.js";
|
|
1
|
+
import { isClientImport, isClientScript, isJsxElement, } from "@backtickjs/core";
|
|
2
|
+
import { expandJsxElement } from "./expandJsxElement.js";
|
|
4
3
|
import { bindingsOf, capturesOf } from "./params.js";
|
|
5
4
|
import { sourceName } from "./bindingKey.js";
|
|
6
|
-
import { array, arrow, call, createNames, imported, literal, object,
|
|
5
|
+
import { array, arrow, call, createNames, imported, literal, object, undefinedValue, } from "../print/code.js";
|
|
7
6
|
// Names a binding may not take: what strict code cannot bind. Every name the
|
|
8
7
|
// bundle introduces starts with `$`, which a script cannot bind, so none of
|
|
9
8
|
// those can meet a binding.
|
|
10
9
|
const RESERVED = ["arguments", "await", "eval", "yield"];
|
|
11
|
-
const rootScope = { bindings: new Set() };
|
|
12
|
-
// Builds the bundle
|
|
13
|
-
// derived.
|
|
10
|
+
const rootScope = () => ({ bindings: new Set(), read: new Set() });
|
|
11
|
+
// Builds the bundle, its modules, constants and root, as code.
|
|
14
12
|
//
|
|
15
13
|
// Each script is declared once, as its compiled code under a label `$cs<n>`,
|
|
16
|
-
// and called wherever it is used. Its code takes a parameter per splice —
|
|
17
|
-
//
|
|
18
|
-
// script's source alone: every call
|
|
19
|
-
// thunks, and nothing from a call site is
|
|
14
|
+
// and called wherever it is used. Its code takes a parameter per splice — a
|
|
15
|
+
// hole reads `$splice<i>(…)`, handing it the hole's bindings — then per
|
|
16
|
+
// capture, so it is a function of the script's source alone: every call
|
|
17
|
+
// passes its own splice arguments, as thunks, and nothing from a call site is
|
|
18
|
+
// inlined.
|
|
20
19
|
//
|
|
21
20
|
// A captured variable is threaded, not resolved by name at the splice site: a
|
|
22
21
|
// fragment written in one script but spliced (via host code) into another still
|
|
@@ -28,7 +27,6 @@ const rootScope = { bindings: new Set() };
|
|
|
28
27
|
// unique name, so there is nothing to disambiguate and nothing to rename.
|
|
29
28
|
export async function buildBundle(value, packageVersions) {
|
|
30
29
|
const names = createNames(packageVersions);
|
|
31
|
-
const elementExpansions = new WeakMap();
|
|
32
30
|
// Each script's number, in the order rendering first reaches it. Two
|
|
33
31
|
// scripts written at one source location are one declaration, so the first
|
|
34
32
|
// script with an id stands for all of them, and a reference to a shared
|
|
@@ -52,13 +50,8 @@ export async function buildBundle(value, packageVersions) {
|
|
|
52
50
|
// Disambiguated at all because these become identifiers, and identifiers nest:
|
|
53
51
|
// a hole inside a thunk puts one thunk's parameters inside another's, so two
|
|
54
52
|
// bindings sharing a source name can land in one chain and the inner would
|
|
55
|
-
// shadow what the outer was handed (`shadowing` nests three).
|
|
56
|
-
//
|
|
57
|
-
// One scope, which is the bundle root: what a drawing is written into now
|
|
58
|
-
// that structure goes where it stands. A declared script's names are the
|
|
59
|
-
// compiler's, from its own source — nothing out here reads those names,
|
|
60
|
-
// because a call hands a script its arguments positionally, and its
|
|
61
|
-
// captures arrive as numbered parameters rather than under a name.
|
|
53
|
+
// shadow what the outer was handed (`shadowing` nests three). A script's own
|
|
54
|
+
// names are the compiler's: a call hands it its arguments by position.
|
|
62
55
|
const displayed = new Map();
|
|
63
56
|
const used = new Set(RESERVED);
|
|
64
57
|
const displayName = (key) => {
|
|
@@ -91,43 +84,53 @@ export async function buildBundle(value, packageVersions) {
|
|
|
91
84
|
// decision. A carried fragment arrives with its own captures already bound,
|
|
92
85
|
// so the extra parameters are unused rather than wrong.
|
|
93
86
|
const passKeys = (target, hole) => bindingsOf(target.module.params[hole]);
|
|
94
|
-
//
|
|
95
|
-
// every one looked up on the way.
|
|
96
|
-
const declared = new Set();
|
|
97
|
-
// A declared script's label: `$cs` and its number.
|
|
87
|
+
// A script's label: `$cs` and its number.
|
|
98
88
|
const labelOf = (target) => `$cs${numbers.get(target)}`;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
89
|
+
// Every function the bundle writes is a closure: a function script, and the
|
|
90
|
+
// thunk a splice is handed over as. One whose code reads nothing of the
|
|
91
|
+
// scope it's written in, beyond its own parameters, is the same function
|
|
92
|
+
// wherever it's written, so the bundle makes it once, as a constant, and
|
|
93
|
+
// the same code anywhere else is that constant: a client component keeps
|
|
94
|
+
// its identity across renders, and a value spliced at every level of a deep
|
|
95
|
+
// composition is written once per level, not once per path. Making a
|
|
96
|
+
// function runs nothing, so sharing one isn't observable; everything is
|
|
97
|
+
// still rendered where it stands.
|
|
98
|
+
const constants = [];
|
|
99
|
+
const byCode = new Map();
|
|
100
|
+
// `write` renders a closure's code in a scope that records what it reads:
|
|
101
|
+
// a constant's label if it read nothing of `scope` beyond `own`, its
|
|
102
|
+
// parameters, or else the code, written where it's used.
|
|
103
|
+
const closure = async (scope, own, write, name) => {
|
|
104
|
+
const read = new Set();
|
|
105
|
+
const code = await write({
|
|
106
|
+
bindings: new Set([...scope.bindings, ...own]),
|
|
107
|
+
read,
|
|
108
|
+
});
|
|
109
|
+
const outside = [...read].filter((key) => !own.includes(key) && scope.bindings.has(key));
|
|
110
|
+
if (outside.length > 0) {
|
|
111
|
+
outside.forEach((key) => scope.read.add(key));
|
|
112
|
+
return code;
|
|
113
|
+
}
|
|
114
|
+
let label = byCode.get(code);
|
|
115
|
+
if (label === undefined) {
|
|
116
|
+
label = `${name}${constants.length}`;
|
|
117
|
+
byCode.set(code, label);
|
|
118
|
+
constants.push([label, code]);
|
|
119
|
+
}
|
|
120
|
+
return label;
|
|
120
121
|
};
|
|
121
122
|
// Writes a value as the code it becomes: composition as data, which is what
|
|
122
123
|
// a bundle is. A script reference is a call naming which script and
|
|
123
124
|
// what to hand it; everything else is its literal form. Rendered in order,
|
|
124
125
|
// one value after the other, so the table follows the order rendering first
|
|
125
126
|
// reached each script.
|
|
126
|
-
const render = async (value, scope = rootScope) => {
|
|
127
|
+
const render = async (value, scope = rootScope()) => {
|
|
127
128
|
if (isClientScript(value)) {
|
|
128
129
|
const target = scriptFor(value);
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
if (target.module.kind !== "function") {
|
|
131
|
+
return call(labelOf(target), await exprCallArgs(value, scope));
|
|
132
|
+
}
|
|
133
|
+
return closure(scope, [], async (inner) => call(labelOf(target), await exprCallArgs(value, inner)), "$function");
|
|
131
134
|
}
|
|
132
135
|
if (isJsxElement(value)) {
|
|
133
136
|
return renderJsx(value, scope);
|
|
@@ -183,13 +186,12 @@ export async function buildBundle(value, packageVersions) {
|
|
|
183
186
|
}
|
|
184
187
|
return object(entries);
|
|
185
188
|
};
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
// At
|
|
189
|
-
// the bundle root there is no enclosing instance, so a capture reaching it
|
|
189
|
+
// A capture, by the name an enclosing thunk was handed it under, recorded as
|
|
190
|
+
// read. At the bundle root nothing encloses it, so a capture reaching there
|
|
190
191
|
// can't be threaded from anywhere.
|
|
191
192
|
const capExpr = (key, scope) => {
|
|
192
193
|
if (scope.bindings.has(key)) {
|
|
194
|
+
scope.read.add(key);
|
|
193
195
|
return displayName(key);
|
|
194
196
|
}
|
|
195
197
|
throw new Error(`Can't thread the capture \`${sourceName(key)}\`: nothing encloses ` +
|
|
@@ -201,8 +203,8 @@ export async function buildBundle(value, packageVersions) {
|
|
|
201
203
|
"name, and naming it anyway would mean emitting what the source " +
|
|
202
204
|
"couldn't say.");
|
|
203
205
|
};
|
|
204
|
-
// The arguments of a call of a
|
|
205
|
-
//
|
|
206
|
+
// The arguments of a call of a script: a thunk per splice, then its
|
|
207
|
+
// captures.
|
|
206
208
|
const exprCallArgs = async (ref, scope) => {
|
|
207
209
|
const target = scriptFor(ref);
|
|
208
210
|
const parts = [];
|
|
@@ -212,21 +214,8 @@ export async function buildBundle(value, packageVersions) {
|
|
|
212
214
|
// bound there, then the captures it forwards on behalf of whatever is
|
|
213
215
|
// nested inside it.
|
|
214
216
|
const passed = [...passKeys(target, index), ...capturesOf(target)];
|
|
215
|
-
// A
|
|
216
|
-
|
|
217
|
-
// in a thunk that would only pass them along.
|
|
218
|
-
const forwarded = forwarding(arg, passed);
|
|
219
|
-
if (forwarded !== null) {
|
|
220
|
-
parts.push(forwarded);
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
if (passed.length === 0) {
|
|
224
|
-
parts.push(thunk(await render(arg, scope)));
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
// Otherwise a thunk names them and calls the fragment with what it wants.
|
|
228
|
-
const inner = { bindings: new Set([...scope.bindings, ...passed]) };
|
|
229
|
-
parts.push(arrow(passed.map(displayName), await render(arg, inner)));
|
|
217
|
+
// A thunk taking them, the splice rendered inside it.
|
|
218
|
+
parts.push(await closure(scope, passed, async (inner) => arrow(passed.map(displayName), await render(arg, inner)), "$thunk"));
|
|
230
219
|
}
|
|
231
220
|
for (const key of capturesOf(target)) {
|
|
232
221
|
parts.push(capExpr(key, scope));
|
|
@@ -243,7 +232,7 @@ export async function buildBundle(value, packageVersions) {
|
|
|
243
232
|
const renderJsx = async (jsx, scope) => {
|
|
244
233
|
const type = jsx.type;
|
|
245
234
|
if (typeof type === "function" && !isClientImport(type)) {
|
|
246
|
-
return render(await expandJsxElement(jsx, type
|
|
235
|
+
return render(await expandJsxElement(jsx, type), scope);
|
|
247
236
|
}
|
|
248
237
|
// An element and a client component (an import, or a script answering
|
|
249
238
|
// one) are client code, so on the host they can't be tags: they are tags
|
|
@@ -259,12 +248,7 @@ export async function buildBundle(value, packageVersions) {
|
|
|
259
248
|
// Nothing encloses the root, so nothing it holds can capture.
|
|
260
249
|
const root = await render(value);
|
|
261
250
|
// In table order, which is the order rendering first reached each script.
|
|
262
|
-
const modules = [];
|
|
263
|
-
|
|
264
|
-
if (declared.has(script)) {
|
|
265
|
-
modules.push([labelOf(script), script.module]);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return { modules, root, names };
|
|
251
|
+
const modules = [...numbers.keys()].map((script) => [labelOf(script), script.module]);
|
|
252
|
+
return { modules, constants, root, names };
|
|
269
253
|
}
|
|
270
254
|
//# sourceMappingURL=buildBundle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildBundle.js","sourceRoot":"","sources":["../../src/bundle/buildBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EACd,YAAY,
|
|
1
|
+
{"version":3,"file":"buildBundle.js","sourceRoot":"","sources":["../../src/bundle/buildBundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import type { JsxElement, Spliceable } from "@backtickjs/core";
|
|
2
|
-
export
|
|
3
|
-
export declare function expandJsxElement(jsx: JsxElement, component: (props: never) => unknown, expansions: ElementExpansions): Promise<Spliceable>;
|
|
2
|
+
export declare function expandJsxElement(jsx: JsxElement, component: (props: never) => unknown): Promise<Spliceable>;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
// Runs a host component and answers with what it drew
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return shared;
|
|
8
|
-
}
|
|
9
|
-
const expansion = Promise.resolve(component(jsx.props));
|
|
10
|
-
expansions.set(jsx, expansion);
|
|
11
|
-
return expansion;
|
|
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 (await component(jsx.props));
|
|
12
7
|
}
|
|
13
8
|
//# sourceMappingURL=expandJsxElement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expandJsxElement.js","sourceRoot":"","sources":["../../src/bundle/expandJsxElement.ts"],"names":[],"mappings":"
|
|
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,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,KAAc,CAAC,CAAe,CAAC;AAC7D,CAAC"}
|
package/dist/print/code.d.ts
CHANGED
|
@@ -17,7 +17,6 @@ export declare function literal(value: string | number | boolean | null): string
|
|
|
17
17
|
export declare const undefinedValue = "void 0";
|
|
18
18
|
export declare function call(callee: string, args: readonly string[]): string;
|
|
19
19
|
export declare function arrow(params: readonly string[], body: string): string;
|
|
20
|
-
export declare function thunk(body: string): string;
|
|
21
20
|
export declare function array(elements: readonly string[]): string;
|
|
22
21
|
/** An object literal, each key bare where it can be and a string where not. */
|
|
23
22
|
export declare function object(entries: readonly (readonly [string, string])[]): string;
|
package/dist/print/code.js
CHANGED
|
@@ -33,9 +33,6 @@ export function call(callee, args) {
|
|
|
33
33
|
export function arrow(params, body) {
|
|
34
34
|
return `(${params.join(", ")}) => (${body})`;
|
|
35
35
|
}
|
|
36
|
-
export function thunk(body) {
|
|
37
|
-
return arrow([], body);
|
|
38
|
-
}
|
|
39
36
|
export function array(elements) {
|
|
40
37
|
return `[${elements.join(", ")}]`;
|
|
41
38
|
}
|
package/dist/print/code.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/print/code.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,6EAA6E;AAC7E,+EAA+E;AAC/E,iEAAiE;AAEjE,MAAM,UAAU,GAAG,4BAA4B,CAAC;AAWhD,MAAM,UAAU,WAAW,CACzB,eAAiD;IAEjD,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,eAAe,EAAE,CAAC;AACjD,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,CAAC,KAAuC;IAC7D,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,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC;QAC7C,CAAC;QACD,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,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEvC,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,
|
|
1
|
+
{"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/print/code.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,6 +60,9 @@ export function printBundle(tree, format) {
|
|
|
60
60
|
for (const [label, entry] of tree.modules) {
|
|
61
61
|
module.line(`const ${label} = $require(${string(entry.id)}).default;`);
|
|
62
62
|
}
|
|
63
|
+
for (const [label, code] of tree.constants) {
|
|
64
|
+
module.line(`const ${label} = ${code};`);
|
|
65
|
+
}
|
|
63
66
|
// Parenthesized, so a root that is a function isn't a declaration.
|
|
64
67
|
module.write(format === "es"
|
|
65
68
|
? `export default (${tree.root});`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printBundle.js","sourceRoot":"","sources":["../../src/print/printBundle.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"printBundle.js","sourceRoot":"","sources":["../../src/print/printBundle.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backtickjs/bundler",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"semver": "^7.8.1",
|
|
43
|
-
"@backtickjs/core": "0.1.
|
|
43
|
+
"@backtickjs/core": "0.1.3"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/semver": "^7.8.0",
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ClientModule,
|
|
3
3
|
type ClientScript,
|
|
4
|
+
isClientImport,
|
|
4
5
|
isClientScript,
|
|
5
6
|
isJsxElement,
|
|
6
7
|
type JsxElement,
|
|
8
|
+
type Spliceable,
|
|
7
9
|
} from "@backtickjs/core";
|
|
8
|
-
import { isClientImport, type Spliceable } from "@backtickjs/core";
|
|
9
10
|
|
|
10
|
-
import {
|
|
11
|
-
type ElementExpansions,
|
|
12
|
-
expandJsxElement,
|
|
13
|
-
} from "./expandJsxElement.js";
|
|
11
|
+
import { expandJsxElement } from "./expandJsxElement.js";
|
|
14
12
|
import { bindingsOf, capturesOf } from "./params.js";
|
|
15
13
|
import { sourceName } from "./bindingKey.js";
|
|
16
14
|
import {
|
|
@@ -21,7 +19,6 @@ import {
|
|
|
21
19
|
imported,
|
|
22
20
|
literal,
|
|
23
21
|
object,
|
|
24
|
-
thunk,
|
|
25
22
|
undefinedValue,
|
|
26
23
|
} from "../print/code.js";
|
|
27
24
|
import type { Names } from "../print/code.js";
|
|
@@ -33,6 +30,9 @@ import type { Names } from "../print/code.js";
|
|
|
33
30
|
*/
|
|
34
31
|
export interface BundleTree {
|
|
35
32
|
readonly modules: readonly (readonly [string, ClientModule])[];
|
|
33
|
+
// The functions the bundle makes once, each under its label, in the order
|
|
34
|
+
// they're finished: after what they read.
|
|
35
|
+
readonly constants: readonly (readonly [string, string])[];
|
|
36
36
|
readonly root: string;
|
|
37
37
|
readonly names: Names;
|
|
38
38
|
}
|
|
@@ -43,21 +43,23 @@ export interface BundleTree {
|
|
|
43
43
|
const RESERVED = ["arguments", "await", "eval", "yield"];
|
|
44
44
|
|
|
45
45
|
// What encloses a value being rendered: the bindings the thunks around it were
|
|
46
|
-
// handed
|
|
46
|
+
// handed, and those read through it, as `capExpr` resolves them, which the
|
|
47
|
+
// scopes a hole opens inside it share.
|
|
47
48
|
interface Scope {
|
|
48
49
|
readonly bindings: ReadonlySet<string>;
|
|
50
|
+
readonly read: Set<string>;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
const rootScope: Scope
|
|
53
|
+
const rootScope = (): Scope => ({ bindings: new Set(), read: new Set() });
|
|
52
54
|
|
|
53
|
-
// Builds the bundle
|
|
54
|
-
// derived.
|
|
55
|
+
// Builds the bundle, its modules, constants and root, as code.
|
|
55
56
|
//
|
|
56
57
|
// Each script is declared once, as its compiled code under a label `$cs<n>`,
|
|
57
|
-
// and called wherever it is used. Its code takes a parameter per splice —
|
|
58
|
-
//
|
|
59
|
-
// script's source alone: every call
|
|
60
|
-
// thunks, and nothing from a call site is
|
|
58
|
+
// and called wherever it is used. Its code takes a parameter per splice — a
|
|
59
|
+
// hole reads `$splice<i>(…)`, handing it the hole's bindings — then per
|
|
60
|
+
// capture, so it is a function of the script's source alone: every call
|
|
61
|
+
// passes its own splice arguments, as thunks, and nothing from a call site is
|
|
62
|
+
// inlined.
|
|
61
63
|
//
|
|
62
64
|
// A captured variable is threaded, not resolved by name at the splice site: a
|
|
63
65
|
// fragment written in one script but spliced (via host code) into another still
|
|
@@ -72,7 +74,6 @@ export async function buildBundle(
|
|
|
72
74
|
packageVersions: Readonly<Record<string, string>>,
|
|
73
75
|
): Promise<BundleTree> {
|
|
74
76
|
const names = createNames(packageVersions);
|
|
75
|
-
const elementExpansions: ElementExpansions = new WeakMap();
|
|
76
77
|
// Each script's number, in the order rendering first reaches it. Two
|
|
77
78
|
// scripts written at one source location are one declaration, so the first
|
|
78
79
|
// script with an id stands for all of them, and a reference to a shared
|
|
@@ -96,13 +97,8 @@ export async function buildBundle(
|
|
|
96
97
|
// Disambiguated at all because these become identifiers, and identifiers nest:
|
|
97
98
|
// a hole inside a thunk puts one thunk's parameters inside another's, so two
|
|
98
99
|
// bindings sharing a source name can land in one chain and the inner would
|
|
99
|
-
// shadow what the outer was handed (`shadowing` nests three).
|
|
100
|
-
//
|
|
101
|
-
// One scope, which is the bundle root: what a drawing is written into now
|
|
102
|
-
// that structure goes where it stands. A declared script's names are the
|
|
103
|
-
// compiler's, from its own source — nothing out here reads those names,
|
|
104
|
-
// because a call hands a script its arguments positionally, and its
|
|
105
|
-
// captures arrive as numbered parameters rather than under a name.
|
|
100
|
+
// shadow what the outer was handed (`shadowing` nests three). A script's own
|
|
101
|
+
// names are the compiler's: a call hands it its arguments by position.
|
|
106
102
|
const displayed = new Map<string, string>();
|
|
107
103
|
const used = new Set<string>(RESERVED);
|
|
108
104
|
const displayName = (key: string): string => {
|
|
@@ -138,43 +134,49 @@ export async function buildBundle(
|
|
|
138
134
|
const passKeys = (target: ClientScript, hole: number): readonly string[] =>
|
|
139
135
|
bindingsOf(target.module.params[hole]);
|
|
140
136
|
|
|
141
|
-
//
|
|
142
|
-
// every one looked up on the way.
|
|
143
|
-
const declared = new Set<ClientScript>();
|
|
144
|
-
|
|
145
|
-
// A declared script's label: `$cs` and its number.
|
|
137
|
+
// A script's label: `$cs` and its number.
|
|
146
138
|
const labelOf = (target: ClientScript): string =>
|
|
147
139
|
`$cs${numbers.get(target)!}`;
|
|
148
140
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
141
|
+
// Every function the bundle writes is a closure: a function script, and the
|
|
142
|
+
// thunk a splice is handed over as. One whose code reads nothing of the
|
|
143
|
+
// scope it's written in, beyond its own parameters, is the same function
|
|
144
|
+
// wherever it's written, so the bundle makes it once, as a constant, and
|
|
145
|
+
// the same code anywhere else is that constant: a client component keeps
|
|
146
|
+
// its identity across renders, and a value spliced at every level of a deep
|
|
147
|
+
// composition is written once per level, not once per path. Making a
|
|
148
|
+
// function runs nothing, so sharing one isn't observable; everything is
|
|
149
|
+
// still rendered where it stands.
|
|
150
|
+
const constants: (readonly [string, string])[] = [];
|
|
151
|
+
const byCode = new Map<string, string>();
|
|
152
|
+
// `write` renders a closure's code in a scope that records what it reads:
|
|
153
|
+
// a constant's label if it read nothing of `scope` beyond `own`, its
|
|
154
|
+
// parameters, or else the code, written where it's used.
|
|
155
|
+
const closure = async (
|
|
156
|
+
scope: Scope,
|
|
157
|
+
own: readonly string[],
|
|
158
|
+
write: (inner: Scope) => Promise<string>,
|
|
159
|
+
name: string,
|
|
160
|
+
): Promise<string> => {
|
|
161
|
+
const read = new Set<string>();
|
|
162
|
+
const code = await write({
|
|
163
|
+
bindings: new Set([...scope.bindings, ...own]),
|
|
164
|
+
read,
|
|
165
|
+
});
|
|
166
|
+
const outside = [...read].filter(
|
|
167
|
+
(key) => !own.includes(key) && scope.bindings.has(key),
|
|
168
|
+
);
|
|
169
|
+
if (outside.length > 0) {
|
|
170
|
+
outside.forEach((key) => scope.read.add(key));
|
|
171
|
+
return code;
|
|
167
172
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
) {
|
|
174
|
-
return null;
|
|
173
|
+
let label = byCode.get(code);
|
|
174
|
+
if (label === undefined) {
|
|
175
|
+
label = `${name}${constants.length}`;
|
|
176
|
+
byCode.set(code, label);
|
|
177
|
+
constants.push([label, code]);
|
|
175
178
|
}
|
|
176
|
-
|
|
177
|
-
return labelOf(target);
|
|
179
|
+
return label;
|
|
178
180
|
};
|
|
179
181
|
|
|
180
182
|
// Writes a value as the code it becomes: composition as data, which is what
|
|
@@ -184,12 +186,20 @@ export async function buildBundle(
|
|
|
184
186
|
// reached each script.
|
|
185
187
|
const render = async (
|
|
186
188
|
value: Spliceable,
|
|
187
|
-
scope: Scope = rootScope,
|
|
189
|
+
scope: Scope = rootScope(),
|
|
188
190
|
): Promise<string> => {
|
|
189
191
|
if (isClientScript(value)) {
|
|
190
192
|
const target = scriptFor(value);
|
|
191
|
-
|
|
192
|
-
|
|
193
|
+
if (target.module.kind !== "function") {
|
|
194
|
+
return call(labelOf(target), await exprCallArgs(value, scope));
|
|
195
|
+
}
|
|
196
|
+
return closure(
|
|
197
|
+
scope,
|
|
198
|
+
[],
|
|
199
|
+
async (inner) =>
|
|
200
|
+
call(labelOf(target), await exprCallArgs(value, inner)),
|
|
201
|
+
"$function",
|
|
202
|
+
);
|
|
193
203
|
}
|
|
194
204
|
if (isJsxElement(value)) {
|
|
195
205
|
return renderJsx(value, scope);
|
|
@@ -252,13 +262,12 @@ export async function buildBundle(
|
|
|
252
262
|
return object(entries);
|
|
253
263
|
};
|
|
254
264
|
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
// At
|
|
258
|
-
// the bundle root there is no enclosing instance, so a capture reaching it
|
|
265
|
+
// A capture, by the name an enclosing thunk was handed it under, recorded as
|
|
266
|
+
// read. At the bundle root nothing encloses it, so a capture reaching there
|
|
259
267
|
// can't be threaded from anywhere.
|
|
260
268
|
const capExpr = (key: string, scope: Scope): string => {
|
|
261
269
|
if (scope.bindings.has(key)) {
|
|
270
|
+
scope.read.add(key);
|
|
262
271
|
return displayName(key);
|
|
263
272
|
}
|
|
264
273
|
throw new Error(
|
|
@@ -273,8 +282,8 @@ export async function buildBundle(
|
|
|
273
282
|
);
|
|
274
283
|
};
|
|
275
284
|
|
|
276
|
-
// The arguments of a call of a
|
|
277
|
-
//
|
|
285
|
+
// The arguments of a call of a script: a thunk per splice, then its
|
|
286
|
+
// captures.
|
|
278
287
|
const exprCallArgs = async (
|
|
279
288
|
ref: ClientScript,
|
|
280
289
|
scope: Scope,
|
|
@@ -287,21 +296,16 @@ export async function buildBundle(
|
|
|
287
296
|
// bound there, then the captures it forwards on behalf of whatever is
|
|
288
297
|
// nested inside it.
|
|
289
298
|
const passed = [...passKeys(target, index), ...capturesOf(target)];
|
|
290
|
-
// A
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
// Otherwise a thunk names them and calls the fragment with what it wants.
|
|
303
|
-
const inner = { bindings: new Set([...scope.bindings, ...passed]) };
|
|
304
|
-
parts.push(arrow(passed.map(displayName), await render(arg, inner)));
|
|
299
|
+
// A thunk taking them, the splice rendered inside it.
|
|
300
|
+
parts.push(
|
|
301
|
+
await closure(
|
|
302
|
+
scope,
|
|
303
|
+
passed,
|
|
304
|
+
async (inner) =>
|
|
305
|
+
arrow(passed.map(displayName), await render(arg, inner)),
|
|
306
|
+
"$thunk",
|
|
307
|
+
),
|
|
308
|
+
);
|
|
305
309
|
}
|
|
306
310
|
for (const key of capturesOf(target)) {
|
|
307
311
|
parts.push(capExpr(key, scope));
|
|
@@ -319,10 +323,7 @@ export async function buildBundle(
|
|
|
319
323
|
const renderJsx = async (jsx: JsxElement, scope: Scope): Promise<string> => {
|
|
320
324
|
const type = jsx.type;
|
|
321
325
|
if (typeof type === "function" && !isClientImport(type)) {
|
|
322
|
-
return render(
|
|
323
|
-
await expandJsxElement(jsx, type, elementExpansions),
|
|
324
|
-
scope,
|
|
325
|
-
);
|
|
326
|
+
return render(await expandJsxElement(jsx, type), scope);
|
|
326
327
|
}
|
|
327
328
|
// An element and a client component (an import, or a script answering
|
|
328
329
|
// one) are client code, so on the host they can't be tags: they are tags
|
|
@@ -343,11 +344,8 @@ export async function buildBundle(
|
|
|
343
344
|
// Nothing encloses the root, so nothing it holds can capture.
|
|
344
345
|
const root = await render(value as Spliceable);
|
|
345
346
|
// In table order, which is the order rendering first reached each script.
|
|
346
|
-
const modules
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return { modules, root, names };
|
|
347
|
+
const modules = [...numbers.keys()].map(
|
|
348
|
+
(script) => [labelOf(script), script.module] as const,
|
|
349
|
+
);
|
|
350
|
+
return { modules, constants, root, names };
|
|
353
351
|
}
|
|
@@ -1,26 +1,12 @@
|
|
|
1
1
|
import type { JsxElement, Spliceable } from "@backtickjs/core";
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
// Runs a host component and answers with what it drew. The component itself
|
|
10
|
-
// never leaves the host: a server component expands away here, and only the
|
|
11
|
-
// client component it bottoms out in reaches the bundle.
|
|
12
|
-
export function expandJsxElement(
|
|
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(
|
|
13
8
|
jsx: JsxElement,
|
|
14
9
|
component: (props: never) => unknown,
|
|
15
|
-
expansions: ElementExpansions,
|
|
16
10
|
): Promise<Spliceable> {
|
|
17
|
-
|
|
18
|
-
if (shared) {
|
|
19
|
-
return shared;
|
|
20
|
-
}
|
|
21
|
-
const expansion = Promise.resolve(
|
|
22
|
-
component(jsx.props as never) as Spliceable | Promise<Spliceable>,
|
|
23
|
-
);
|
|
24
|
-
expansions.set(jsx, expansion);
|
|
25
|
-
return expansion;
|
|
11
|
+
return (await component(jsx.props as never)) as Spliceable;
|
|
26
12
|
}
|
package/src/print/code.ts
CHANGED
|
@@ -57,10 +57,6 @@ export function arrow(params: readonly string[], body: string): string {
|
|
|
57
57
|
return `(${params.join(", ")}) => (${body})`;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export function thunk(body: string): string {
|
|
61
|
-
return arrow([], body);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
60
|
export function array(elements: readonly string[]): string {
|
|
65
61
|
return `[${elements.join(", ")}]`;
|
|
66
62
|
}
|
package/src/print/printBundle.ts
CHANGED
|
@@ -74,6 +74,9 @@ export function printBundle(
|
|
|
74
74
|
for (const [label, entry] of tree.modules) {
|
|
75
75
|
module.line(`const ${label} = $require(${string(entry.id)}).default;`);
|
|
76
76
|
}
|
|
77
|
+
for (const [label, code] of tree.constants) {
|
|
78
|
+
module.line(`const ${label} = ${code};`);
|
|
79
|
+
}
|
|
77
80
|
// Parenthesized, so a root that is a function isn't a declaration.
|
|
78
81
|
module.write(
|
|
79
82
|
format === "es"
|