@backtickjs/bundler 0.1.11 → 0.2.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/README.md CHANGED
@@ -34,7 +34,7 @@ For the web, write an ES module whose default export is the value, and load it w
34
34
  ```tsx
35
35
  import { bundler } from "@backtickjs/bundler";
36
36
  import { cs } from "@backtickjs/core";
37
- import { createRoot } from "@backtickjs/react/client";
37
+ import { createRoot } from "react-dom/client" with { backtick: "client" };
38
38
  import { Home } from "./Home.js";
39
39
 
40
40
  const element = <Home />;
@@ -51,7 +51,7 @@ const { code } = build.generate({ format: "es", sourcemap: "inline" });
51
51
 
52
52
  ### `modules`
53
53
 
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`.
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 is typed against a version the one given isn't compatible with: an earlier one, or another major. `19.2.3` for `react` takes any later 19.x.
55
55
 
56
56
  `supports(modules, specifier, range)` makes the same check, for a server choosing what to draw for a client: `supports(modules, "expo-haptics", "^15")`.
57
57
 
@@ -77,7 +77,7 @@ Spliced values are written into the bundle as data, never as code. What can't cr
77
77
  ## Related
78
78
 
79
79
  - [`@backtickjs/core`](https://github.com/backtickjs/backtick/tree/main/packages/core): the `cs` tag, and `execRoot`, which runs a bundle in the app
80
- - [`@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
80
+ - [`@backtickjs/jsx-react`](https://github.com/backtickjs/backtick/tree/main/packages/jsx-react), [`@backtickjs/jsx-solid`](https://github.com/backtickjs/backtick/tree/main/packages/jsx-solid): each framework's JSX
81
81
  - [How it works](https://backtickjs.com/docs/how-it-works/)
82
82
  - [Errors](https://backtickjs.com/docs/errors/)
83
83
 
@@ -1,4 +1,4 @@
1
- import { type ClientModule } from "@backtickjs/core";
1
+ import { type ScriptModule } from "@backtickjs/core";
2
2
  import type { Names } from "../print/code.js";
3
3
  import type { Modules } from "../modules.js";
4
4
  /**
@@ -7,7 +7,7 @@ import type { Modules } from "../modules.js";
7
7
  * root, as code; and what they import.
8
8
  */
9
9
  export interface BundleTree {
10
- readonly modules: readonly (readonly [string, ClientModule])[];
10
+ readonly modules: readonly (readonly [string, ScriptModule])[];
11
11
  readonly constants: readonly (readonly [string, string])[];
12
12
  readonly root: string;
13
13
  readonly names: Names;
@@ -23,6 +23,6 @@ export declare function array(elements: readonly string[]): string;
23
23
  export declare function object(entries: readonly (readonly [string, string])[]): string;
24
24
  /** An export of a module the client provides, imported by the bundle. */
25
25
  export declare function imported(names: Names, { from, name, version }: ClientImport<unknown>): string;
26
- /** An import declaration of one export under its local name. */
26
+ /** An import declaration of one export, or the namespace (`*`), by its local name. */
27
27
  export declare function importDeclaration(from: string, name: string, local: string): string;
28
28
  export declare function requireDeclaration(from: string, name: string, local: string): string;
@@ -60,9 +60,10 @@ export function imported(names, { from, name, version }) {
60
60
  throw new Error(`Can't import \`${name}\` from "${from}": the client provides ` +
61
61
  `${listed.join(", ") || "no modules"}.`);
62
62
  }
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}.`);
63
+ // Typed against one version, it works with a later one of the same major.
64
+ if (!supports(names.modules, from, `^${version}`)) {
65
+ throw new Error(`Can't import \`${name}\` from "${from}": it's typed against ` +
66
+ `${version}, and the client provides ${from}@${provided}.`);
66
67
  }
67
68
  const key = `${from}\0${name}`;
68
69
  let entry = names.imports.get(key);
@@ -72,13 +73,19 @@ export function imported(names, { from, name, version }) {
72
73
  }
73
74
  return entry.local;
74
75
  }
75
- /** An import declaration of one export under its local name. */
76
+ /** An import declaration of one export, or the namespace (`*`), by its local name. */
76
77
  export function importDeclaration(from, name, local) {
78
+ if (name === "*") {
79
+ return `import * as ${local} from ${string(from)};`;
80
+ }
77
81
  const exported = IDENTIFIER.test(name) ? name : string(name);
78
82
  return `import { ${exported} as ${local} } from ${string(from)};`;
79
83
  }
80
84
  // The same import as CommonJS writes it: `const { name: local } = require(…);`.
81
85
  export function requireDeclaration(from, name, local) {
86
+ if (name === "*") {
87
+ return `const ${local} = require(${string(from)});`;
88
+ }
82
89
  const exported = IDENTIFIER.test(name) ? name : string(name);
83
90
  return `const { ${exported}: ${local} } = require(${string(from)});`;
84
91
  }
@@ -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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtickjs/bundler",
3
- "version": "0.1.11",
3
+ "version": "0.2.0",
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,7 +39,7 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@backtickjs/core": "^0.1.11",
42
+ "@backtickjs/core": "^0.2.0",
43
43
  "semver": "^7.8.1"
44
44
  },
45
45
  "devDependencies": {
@@ -1,5 +1,5 @@
1
1
  import {
2
- type ClientModule,
2
+ type ScriptModule,
3
3
  type ClientScript,
4
4
  isClientExec,
5
5
  isClientImport,
@@ -29,7 +29,7 @@ import type { Modules } from "../modules.js";
29
29
  * root, as code; and what they import.
30
30
  */
31
31
  export interface BundleTree {
32
- readonly modules: readonly (readonly [string, ClientModule])[];
32
+ readonly modules: readonly (readonly [string, ScriptModule])[];
33
33
  // The functions and `once` values the bundle makes once, each under its
34
34
  // label, in the order they're finished: after what they read.
35
35
  readonly constants: readonly (readonly [string, string])[];
package/src/print/code.ts CHANGED
@@ -97,10 +97,11 @@ export function imported(
97
97
  `${listed.join(", ") || "no modules"}.`,
98
98
  );
99
99
  }
100
- if (!supports(names.modules, from, version)) {
100
+ // Typed against one version, it works with a later one of the same major.
101
+ if (!supports(names.modules, from, `^${version}`)) {
101
102
  throw new Error(
102
- `Can't import \`${name}\` from "${from}": it needs ${version}, and ` +
103
- `the client provides ${from}@${provided}.`,
103
+ `Can't import \`${name}\` from "${from}": it's typed against ` +
104
+ `${version}, and the client provides ${from}@${provided}.`,
104
105
  );
105
106
  }
106
107
  const key = `${from}\0${name}`;
@@ -112,12 +113,15 @@ export function imported(
112
113
  return entry.local;
113
114
  }
114
115
 
115
- /** An import declaration of one export under its local name. */
116
+ /** An import declaration of one export, or the namespace (`*`), by its local name. */
116
117
  export function importDeclaration(
117
118
  from: string,
118
119
  name: string,
119
120
  local: string,
120
121
  ): string {
122
+ if (name === "*") {
123
+ return `import * as ${local} from ${string(from)};`;
124
+ }
121
125
  const exported = IDENTIFIER.test(name) ? name : string(name);
122
126
  return `import { ${exported} as ${local} } from ${string(from)};`;
123
127
  }
@@ -128,6 +132,9 @@ export function requireDeclaration(
128
132
  name: string,
129
133
  local: string,
130
134
  ): string {
135
+ if (name === "*") {
136
+ return `const ${local} = require(${string(from)});`;
137
+ }
131
138
  const exported = IDENTIFIER.test(name) ? name : string(name);
132
139
  return `const { ${exported}: ${local} } = require(${string(from)});`;
133
140
  }
@@ -1,5 +1,5 @@
1
1
  import type { BundleTree } from "../bundle/buildBundle.js";
2
- import type { ClientModule } from "@backtickjs/core";
2
+ import type { ScriptModule } from "@backtickjs/core";
3
3
  import { importDeclaration, requireDeclaration, string } from "./code.js";
4
4
 
5
5
  const MODULE_ID = "bundle.js";
@@ -129,7 +129,7 @@ class ModuleWriter {
129
129
  }
130
130
 
131
131
  // A script's code, its map a section of the module's where it starts.
132
- script({ code, map }: ClientModule): void {
132
+ script({ code, map }: ScriptModule): void {
133
133
  this.#sections.push({
134
134
  offset: { line: this.#line, column: this.#column },
135
135
  map: JSON.parse(map) as object,