@backtickjs/bundler 0.0.0-stage → 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jean-François Bisson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,76 @@
1
- # Temporary Holding Version
1
+ # @backtickjs/bundler
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Turns a screen into one JavaScript file for the client. On each request, your server calls `bundler.build` with a server component; the bundler runs it and the server components it draws, and combines their data with the client scripts they return into a bundle. Scripts were already compiled at build time, so nothing is compiled or parsed per request.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @backtickjs/bundler @backtickjs/core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ For React Native, write CommonJS and serve it; the app fetches it and runs it with `evaluate` from `@backtickjs/react-native-client`:
14
+
15
+ ```tsx
16
+ import { bundler } from "@backtickjs/bundler";
17
+ import { Home } from "./Home.js";
18
+
19
+ const packageVersions = { react: "19.2.3", "react-native": "0.86.3" };
20
+
21
+ // In a request handler:
22
+ const bundle = await bundler.build({ input: <Home />, packageVersions });
23
+ const { code } = bundle.generate({ format: "cjs" });
24
+ response.setHeader("content-type", "text/javascript");
25
+ response.end(code);
26
+ ```
27
+
28
+ For the web, write an ES module whose default export is the value, and load it with `<script type="module">` and an import map for the packages the page provides:
29
+
30
+ ```tsx
31
+ import { bundler } from "@backtickjs/bundler";
32
+ import { cs } from "@backtickjs/core";
33
+ import { createRoot } from "@backtickjs/react/client";
34
+ import { Home } from "./Home.js";
35
+
36
+ const element = <Home />;
37
+ const bundle = await bundler.build({
38
+ input: cs`$createRoot(document.getElementById("app")!).render($element)`,
39
+ packageVersions: { react: "19.2.3", "react-dom": "19.2.3" },
40
+ });
41
+ const { code } = bundle.generate({ format: "es", sourcemap: "inline" });
42
+ ```
43
+
44
+ ### `packageVersions`
45
+
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`.
47
+
48
+ ### What crosses into a script
49
+
50
+ Spliced values are written into the bundle as data: strings, finite numbers, booleans, `null`, `undefined`, plain objects and arrays. They are never written as code. A host function or a class instance can't be spliced, and `build` rejects one: write a client function as a script, `` cs`(n: number) => …` ``, and draw a server component through a splice, `{${<Footer />}}`.
51
+
52
+ ### Formats
53
+
54
+ - `"es"`: an ES module, for a web page. Packages are imported by specifier, which the page's import map resolves.
55
+ - `"cjs"`: CommonJS, for a client that provides `require` itself, as a React Native app does through `evaluate`.
56
+
57
+ ### Source maps
58
+
59
+ `sourcemap: "inline"` appends the map to the code as a `data:` URL; `"hidden"` doesn't. Either way, it is also returned as `map`. The map names your server files and lines, not their content. None by default.
60
+
61
+ ## API
62
+
63
+ - `bundler.build({ input, packageVersions })`: runs the server components in `input` and returns a `Bundle`. Async.
64
+ - `Bundle.generate({ format, sourcemap })`: writes the bundle; returns `{ code, map }`, where `map` is `null` without a source map.
65
+ - Types: `BuildOptions`, `OutputOptions`, `OutputChunk`, `Bundle`.
66
+
67
+ ## Related
68
+
69
+ - [`@backtickjs/core`](https://github.com/backtickjs/backtick/tree/main/packages/core): the `cs` tag
70
+ - [`@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
72
+ - [Documentation](https://backtickjs.com/docs)
73
+
74
+ ## License
75
+
76
+ MIT
@@ -0,0 +1 @@
1
+ export declare function sourceName(key: string): string;
@@ -0,0 +1,10 @@
1
+ // A binding key as the compiler writes it, `<name>$<fileHash>$<n>`. Shared by
2
+ // the two halves of the bundler because both have to agree on what a key means,
3
+ // and neither owns it.
4
+ // The source name a key was written under, with the uniqueness suffix dropped.
5
+ // Printing it is the caller's job: two distinct keys can share a source name,
6
+ // and whether that matters depends on whether they can meet in one scope.
7
+ export function sourceName(key) {
8
+ return key.replace(/\$[0-9a-z]+\$\d+$/, "");
9
+ }
10
+ //# sourceMappingURL=bindingKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindingKey.js","sourceRoot":"","sources":["../../src/bundle/bindingKey.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,gFAAgF;AAChF,uBAAuB;AAEvB,+EAA+E;AAC/E,8EAA8E;AAC9E,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type ClientModule } from "@backtickjs/core";
2
+ import { type Spliceable } from "@backtickjs/core";
3
+ import type { Names } from "../print/code.js";
4
+ /**
5
+ * A bundle as it is built, before it is printed: each script's module it
6
+ * declares under its label, in the order rendering first reached it, and the
7
+ * root, as code; and what they import.
8
+ */
9
+ export interface BundleTree {
10
+ readonly modules: readonly (readonly [string, ClientModule])[];
11
+ readonly root: string;
12
+ readonly names: Names;
13
+ }
14
+ export declare function buildBundle(value: Spliceable, packageVersions: Readonly<Record<string, string>>): Promise<BundleTree>;
@@ -0,0 +1,270 @@
1
+ import { isClientScript, isJsxElement, } from "@backtickjs/core";
2
+ import { isClientImport } from "@backtickjs/core";
3
+ import { expandJsxElement, } from "./expandJsxElement.js";
4
+ import { bindingsOf, capturesOf } from "./params.js";
5
+ import { sourceName } from "./bindingKey.js";
6
+ import { array, arrow, call, createNames, imported, literal, object, thunk, undefinedValue, } from "../print/code.js";
7
+ // Names a binding may not take: what strict code cannot bind. Every name the
8
+ // bundle introduces starts with `$`, which a script cannot bind, so none of
9
+ // those can meet a binding.
10
+ const RESERVED = ["arguments", "await", "eval", "yield"];
11
+ const rootScope = { bindings: new Set() };
12
+ // Builds the bundle `{ scripts, root }` as code, and documents how it is
13
+ // derived.
14
+ //
15
+ // 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
+ // a hole reads `$splice<i>()` — then per tag and per capture, so it is a function of the
18
+ // script's source alone: every call passes its own splice arguments, as
19
+ // thunks, and nothing from a call site is inlined.
20
+ //
21
+ // A captured variable is threaded, not resolved by name at the splice site: a
22
+ // fragment written in one script but spliced (via host code) into another still
23
+ // refers to the binding it was written under. Each script receives its live
24
+ // captures as parameters, and a call of it passes those captures from the
25
+ // enclosing scope. Because the compiler gives every binding a globally unique
26
+ // name, a capture is threaded under that one name the whole way down — an
27
+ // intermediate script that binds a same-looking variable has a different
28
+ // unique name, so there is nothing to disambiguate and nothing to rename.
29
+ export async function buildBundle(value, packageVersions) {
30
+ const names = createNames(packageVersions);
31
+ const elementExpansions = new WeakMap();
32
+ // Each script's number, in the order rendering first reaches it. Two
33
+ // scripts written at one source location are one declaration, so the first
34
+ // script with an id stands for all of them, and a reference to a shared
35
+ // script is a reference to the same object. Keyed by that script so a label
36
+ // is a lookup rather than a scan, and ordered by insertion, which is the
37
+ // order the tail declares them in.
38
+ const numbers = new Map();
39
+ const scriptById = new Map();
40
+ const scriptFor = (script) => {
41
+ const existing = scriptById.get(script.module.id);
42
+ if (existing !== undefined) {
43
+ return existing;
44
+ }
45
+ scriptById.set(script.module.id, script);
46
+ numbers.set(script, numbers.size);
47
+ return script;
48
+ };
49
+ // A binding key printed under its source name, with a numeric suffix when two
50
+ // distinct bindings would otherwise print the same.
51
+ //
52
+ // Disambiguated at all because these become identifiers, and identifiers nest:
53
+ // a hole inside a thunk puts one thunk's parameters inside another's, so two
54
+ // 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.
62
+ const displayed = new Map();
63
+ const used = new Set(RESERVED);
64
+ const displayName = (key) => {
65
+ const existing = displayed.get(key);
66
+ if (existing !== undefined) {
67
+ return existing;
68
+ }
69
+ const base = sourceName(key);
70
+ let name = base;
71
+ for (let n = 2; used.has(name); n++) {
72
+ name = `${base}${n}`;
73
+ }
74
+ used.add(name);
75
+ displayed.set(key, name);
76
+ return name;
77
+ };
78
+ // The script-declared bindings a hole feeds its thunk, so a spliced fragment
79
+ // sees the bindings in scope at its hole even though the thunk is written at
80
+ // the call site. The body's hole call and every thunk's parameter list read
81
+ // this, so they agree positionally.
82
+ //
83
+ // Read off the script's own source (see `splices` in `resolveBindings`),
84
+ // not off what the arguments reaching that hole in this bundle happen to
85
+ // capture. That is what lets a script be compiled from its source alone: a
86
+ // second call site appearing elsewhere in a render cannot change a thunk a
87
+ // first one already had.
88
+ //
89
+ // It is a superset — the bindings a fragment written there *could* name, not
90
+ // the ones it does — because which fragment reaches a hole is a host
91
+ // decision. A carried fragment arrives with its own captures already bound,
92
+ // so the extra parameters are unused rather than wrong.
93
+ const passKeys = (target, hole) => bindingsOf(target.module.params[hole]);
94
+ // The scripts the bundle declares: those a reference calls or passes, not
95
+ // every one looked up on the way.
96
+ const declared = new Set();
97
+ // A declared script's label: `$cs` and its number.
98
+ const labelOf = (target) => `$cs${numbers.get(target)}`;
99
+ const declare = (script) => {
100
+ declared.add(script);
101
+ };
102
+ // A fragment that is one script whose parameters are exactly what this hole
103
+ // passes, so calling it is what a thunk around it would have done. The lists
104
+ // are compared rather than assumed: a hole hands over what its own script has,
105
+ // and a fragment wants what its own script needs, and those coincide often
106
+ // but not always.
107
+ const forwarding = (value, passed) => {
108
+ if (!isClientScript(value) ||
109
+ value.module.params.some((param) => param.kind !== "capture")) {
110
+ return null;
111
+ }
112
+ const target = scriptFor(value);
113
+ const wanted = capturesOf(target);
114
+ if (wanted.length !== passed.length ||
115
+ wanted.some((key, at) => key !== passed[at])) {
116
+ return null;
117
+ }
118
+ declare(target);
119
+ return labelOf(target);
120
+ };
121
+ // Writes a value as the code it becomes: composition as data, which is what
122
+ // a bundle is. A script reference is a call naming which script and
123
+ // what to hand it; everything else is its literal form. Rendered in order,
124
+ // one value after the other, so the table follows the order rendering first
125
+ // reached each script.
126
+ const render = async (value, scope = rootScope) => {
127
+ if (isClientScript(value)) {
128
+ const target = scriptFor(value);
129
+ declare(target);
130
+ return call(labelOf(target), await exprCallArgs(value, scope));
131
+ }
132
+ if (isJsxElement(value)) {
133
+ return renderJsx(value, scope);
134
+ }
135
+ if (isClientImport(value)) {
136
+ return imported(names, value);
137
+ }
138
+ if (value === null) {
139
+ return literal(null);
140
+ }
141
+ // Checked by name, since everything past here reads the value as an object.
142
+ if (value === undefined) {
143
+ return undefinedValue;
144
+ }
145
+ if (typeof value === "number" ||
146
+ typeof value === "string" ||
147
+ typeof value === "boolean") {
148
+ return literal(value);
149
+ }
150
+ if (Array.isArray(value)) {
151
+ const elements = [];
152
+ for (const element of value) {
153
+ elements.push(await render(element, scope));
154
+ }
155
+ return array(elements);
156
+ }
157
+ // A host function is host code, which never reaches the client: client
158
+ // code is written in a script, and reaches another as one.
159
+ // A server component among them, written as a tag: `<$Rule />`.
160
+ if (typeof value === "function") {
161
+ const { name } = value;
162
+ throw new Error((name === ""
163
+ ? "Can't splice a host function"
164
+ : `Can't splice the host function \`${name}\``) +
165
+ ": it's host code, and only runs on the host. Write a client " +
166
+ "function as a script instead: cs`(n: number) => ...`; a server " +
167
+ `component is drawn in a braced splice: \`{\${<${name || "Name"} />}}\`.`);
168
+ }
169
+ // Only plain objects cross structurally. A class instance would land here
170
+ // and half-work — own fields would cross, getters and methods silently
171
+ // vanish — so fail loudly instead. An object with behaviour is built by a
172
+ // client function: `state` for what it holds, arrows for what may be done
173
+ // to it.
174
+ const prototype = Object.getPrototypeOf(value);
175
+ if (prototype !== Object.prototype && prototype !== null) {
176
+ const name = value.constructor?.name ?? "an unknown class";
177
+ throw new Error(`Can't splice this \`${name}\` instance: only plain objects cross into ` +
178
+ "a client script. Build one with a client function instead.");
179
+ }
180
+ const entries = [];
181
+ for (const [key, entry] of Object.entries(value)) {
182
+ entries.push([key, await render(entry, scope)]);
183
+ }
184
+ return object(entries);
185
+ };
186
+ // Renders a capture in JSON position: a parameter of an enclosing thunk
187
+ // resolves by name; anything else must be a parameter of the enclosing script.
188
+ // At
189
+ // the bundle root there is no enclosing instance, so a capture reaching it
190
+ // can't be threaded from anywhere.
191
+ const capExpr = (key, scope) => {
192
+ if (scope.bindings.has(key)) {
193
+ return displayName(key);
194
+ }
195
+ throw new Error(`Can't thread the capture \`${sourceName(key)}\`: nothing encloses ` +
196
+ "this reference to supply it. A fragment carries the bindings it was " +
197
+ "written under, so this is also what happens when one is spliced " +
198
+ "somewhere another `" +
199
+ sourceName(key) +
200
+ "` shadows it: the binding is still there, but no longer reachable by " +
201
+ "name, and naming it anyway would mean emitting what the source " +
202
+ "couldn't say.");
203
+ };
204
+ // The arguments of a call of a declared script: for
205
+ // one `#thunk` per splice ahead of the environment.
206
+ const exprCallArgs = async (ref, scope) => {
207
+ const target = scriptFor(ref);
208
+ const parts = [];
209
+ // The splices lead the parameters, one `arg` each.
210
+ for (const [index, arg] of ref.args.entries()) {
211
+ // What the hole hands over, in the order the script fixes: the bindings
212
+ // bound there, then the captures it forwards on behalf of whatever is
213
+ // nested inside it.
214
+ const passed = [...passKeys(target, index), ...capturesOf(target)];
215
+ // A fragment whose own parameters are exactly that list reads the hole's
216
+ // arguments as they arrive, so it is passed as it is rather than wrapped
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)));
230
+ }
231
+ for (const key of capturesOf(target)) {
232
+ parts.push(capExpr(key, scope));
233
+ }
234
+ return parts;
235
+ };
236
+ // A tag. A component runs on the host and what it drew stands where the tag
237
+ // stood; an element is its own name, each prop an expression in the
238
+ // enclosing script's scope.
239
+ //
240
+ // A prop that is `undefined` is left out, as JSX and TypeScript's optional
241
+ // props read it: a component forwarding an optional prop it wasn't given
242
+ // writes nothing.
243
+ const renderJsx = async (jsx, scope) => {
244
+ const type = jsx.type;
245
+ if (typeof type === "function" && !isClientImport(type)) {
246
+ return render(await expandJsxElement(jsx, type, elementExpansions), scope);
247
+ }
248
+ // An element and a client component (an import, or a script answering
249
+ // one) are client code, so on the host they can't be tags: they are tags
250
+ // in a script.
251
+ if (typeof type === "string") {
252
+ throw new Error(`\`<${type}>\` is drawn by the client, so it belongs in a script: ` +
253
+ `cs\`<${type}>…</${type}>\`.`);
254
+ }
255
+ const tag = isClientImport(type) ? `\`<${type.name}>\`` : "A script";
256
+ throw new Error(`${tag} is a client component, so it can't be a tag on the host. ` +
257
+ "Use it as a tag in a script.");
258
+ };
259
+ // Nothing encloses the root, so nothing it holds can capture.
260
+ const root = await render(value);
261
+ // In table order, which is the order rendering first reached each script.
262
+ const modules = [];
263
+ for (const script of numbers.keys()) {
264
+ if (declared.has(script)) {
265
+ modules.push([labelOf(script), script.module]);
266
+ }
267
+ }
268
+ return { modules, root, names };
269
+ }
270
+ //# sourceMappingURL=buildBundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildBundle.js","sourceRoot":"","sources":["../../src/bundle/buildBundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { JsxElement, Spliceable } from "@backtickjs/core";
2
+ export type ElementExpansions = WeakMap<JsxElement, Promise<Spliceable>>;
3
+ export declare function expandJsxElement(jsx: JsxElement, component: (props: never) => unknown, expansions: ElementExpansions): Promise<Spliceable>;
@@ -0,0 +1,13 @@
1
+ // Runs a host component and answers with what it drew. The component itself
2
+ // never leaves the host: a server component expands away here, and only the
3
+ // client component it bottoms out in reaches the bundle.
4
+ export function expandJsxElement(jsx, component, expansions) {
5
+ const shared = expansions.get(jsx);
6
+ if (shared) {
7
+ return shared;
8
+ }
9
+ const expansion = Promise.resolve(component(jsx.props));
10
+ expansions.set(jsx, expansion);
11
+ return expansion;
12
+ }
13
+ //# sourceMappingURL=expandJsxElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expandJsxElement.js","sourceRoot":"","sources":["../../src/bundle/expandJsxElement.ts"],"names":[],"mappings":"AAQA,4EAA4E;AAC5E,4EAA4E;AAC5E,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAC9B,GAAe,EACf,SAAoC,EACpC,UAA6B;IAE7B,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAC/B,SAAS,CAAC,GAAG,CAAC,KAAc,CAAqC,CAClE,CAAC;IACF,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ClientScript, Param } from "@backtickjs/core";
2
+ export declare function bindingsOf(param: Param | undefined): readonly string[];
3
+ export declare function capturesOf(script: ClientScript): readonly string[];
@@ -0,0 +1,10 @@
1
+ // What a script's module says about its parameters, the same for every run.
2
+ // The bindings a hole hands over. A capture hands over none.
3
+ export function bindingsOf(param) {
4
+ return param?.kind === "splice" ? param.bindings : [];
5
+ }
6
+ // The binding keys a script captures, in parameter order.
7
+ export function capturesOf(script) {
8
+ return script.module.params.flatMap((param) => param.kind === "capture" ? [param.key] : []);
9
+ }
10
+ //# sourceMappingURL=params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.js","sourceRoot":"","sources":["../../src/bundle/params.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAE5E,6DAA6D;AAC7D,MAAM,UAAU,UAAU,CAAC,KAAwB;IACjD,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAC5C,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { Spliceable } from "@backtickjs/core";
2
+ export interface BuildOptions {
3
+ readonly input: Spliceable;
4
+ readonly packageVersions: Readonly<Record<string, string>>;
5
+ }
6
+ export interface OutputOptions {
7
+ readonly format: "es" | "cjs";
8
+ readonly sourcemap?: false | "inline" | "hidden";
9
+ }
10
+ /** What `generate` writes: the code, and its map where one was asked for. */
11
+ export interface OutputChunk {
12
+ readonly code: string;
13
+ readonly map: string | null;
14
+ }
15
+ /** A built bundle, written out by `generate`. */
16
+ export interface Bundle {
17
+ generate(options: OutputOptions): OutputChunk;
18
+ }
19
+ /**
20
+ * What runs your components and hands back what they drew, shaped as Rollup
21
+ * is: a build, then output from it.
22
+ *
23
+ * const bundle = await bundler.build({ input: <Home />, packageVersions });
24
+ * const { code, map } = bundle.generate({ format: "es", sourcemap: "hidden" });
25
+ *
26
+ * The module's default export is the value (CommonJS: `module.exports`). A
27
+ * namespace rather than a bare function, so `bundle` stays a name a caller can
28
+ * give what comes back.
29
+ */
30
+ export declare const bundler: {
31
+ build({ input, packageVersions }: BuildOptions): Promise<Bundle>;
32
+ };
@@ -0,0 +1,34 @@
1
+ import { buildBundle } from "./bundle/buildBundle.js";
2
+ import { printBundle } from "./print/printBundle.js";
3
+ /**
4
+ * What runs your components and hands back what they drew, shaped as Rollup
5
+ * is: a build, then output from it.
6
+ *
7
+ * const bundle = await bundler.build({ input: <Home />, packageVersions });
8
+ * const { code, map } = bundle.generate({ format: "es", sourcemap: "hidden" });
9
+ *
10
+ * The module's default export is the value (CommonJS: `module.exports`). A
11
+ * namespace rather than a bare function, so `bundle` stays a name a caller can
12
+ * give what comes back.
13
+ */
14
+ export const bundler = {
15
+ async build({ input, packageVersions }) {
16
+ // Scripts come compiled for their framework when their host was built, so
17
+ // the bundle is only put together: nothing is compiled or parsed here.
18
+ const tree = await buildBundle(input, packageVersions);
19
+ return {
20
+ generate: ({ format, sourcemap = false }) => {
21
+ const { code, map } = printBundle(tree, format);
22
+ if (sourcemap === false) {
23
+ return { code, map: null };
24
+ }
25
+ if (sourcemap === "hidden") {
26
+ return { code, map };
27
+ }
28
+ const url = `data:application/json;charset=utf-8,${encodeURIComponent(map)}`;
29
+ return { code: `${code}\n//# sourceMappingURL=${url}`, map };
30
+ },
31
+ };
32
+ },
33
+ };
34
+ //# sourceMappingURL=bundler.js.map
@@ -0,0 +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,CAAC,EAAE,KAAK,EAAE,eAAe,EAAgB;QAClD,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"}
@@ -0,0 +1 @@
1
+ export { type Bundle, type BuildOptions, bundler, type OutputChunk, type OutputOptions, } from "./bundler.js";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { bundler, } from "./bundler.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,OAAO,GAGR,MAAM,cAAc,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { ClientImport } from "@backtickjs/core";
2
+ /**
3
+ * 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
+ */
6
+ export interface Names {
7
+ readonly imports: Map<string, {
8
+ from: string;
9
+ name: string;
10
+ local: string;
11
+ }>;
12
+ readonly packageVersions: Readonly<Record<string, string>>;
13
+ }
14
+ export declare function createNames(packageVersions: Readonly<Record<string, string>>): Names;
15
+ export declare function string(value: string): string;
16
+ export declare function literal(value: string | number | boolean | null): string;
17
+ export declare const undefinedValue = "void 0";
18
+ export declare function call(callee: string, args: readonly string[]): string;
19
+ export declare function arrow(params: readonly string[], body: string): string;
20
+ export declare function thunk(body: string): string;
21
+ export declare function array(elements: readonly string[]): string;
22
+ /** An object literal, each key bare where it can be and a string where not. */
23
+ export declare function object(entries: readonly (readonly [string, string])[]): string;
24
+ /** An export of a module the client provides, imported by the bundle. */
25
+ export declare function imported(names: Names, { from, name, version }: ClientImport<unknown>): string;
26
+ /** An import declaration of one export under its local name. */
27
+ export declare function importDeclaration(from: string, name: string, local: string): string;
28
+ export declare function requireDeclaration(from: string, name: string, local: string): string;