solid-tag-runtime 0.0.12 → 0.0.13
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/ARCHITECTURE.md +147 -37
- package/README.md +76 -899
- package/docs/README.md +23 -0
- package/docs/api/compile-cache.md +103 -0
- package/docs/api/html.md +83 -0
- package/docs/api/runtime.md +87 -0
- package/docs/compile-cache.md +271 -0
- package/docs/getting-started.md +105 -0
- package/docs/html-runtime.md +112 -0
- package/docs/lifecycle-events.md +77 -0
- package/docs/modules.md +93 -0
- package/docs/rendering.md +65 -0
- package/docs/solid-render.md +111 -0
- package/examples/basic.js +41 -0
- package/examples/compile-cache.js +35 -0
- package/examples/main.tsx +318 -0
- package/examples/render.html +79 -0
- package/index.d.ts +183 -27
- package/package.json +5 -3
- package/src/compile-cache.js +340 -0
- package/src/compiler.js +86 -38
- package/src/index.js +6 -0
- package/src/runtime.js +656 -74
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { render } from "@solidjs/web";
|
|
2
|
+
import * as Solid from "solid-js";
|
|
3
|
+
import * as SolidWeb from "@solidjs/web";
|
|
4
|
+
import html from "@solidjs/html";
|
|
5
|
+
import { createRuntime } from "solid-tag-runtime";
|
|
6
|
+
import { createHTMLRuntime } from "solid-tag-runtime/html";
|
|
7
|
+
|
|
8
|
+
// A tiny type helper for module exports returned by solid-tag-runtime.
|
|
9
|
+
type Component<P = Record<string, unknown>> = (props: P) => any;
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
const root = document.getElementById("root");
|
|
13
|
+
if (!root) throw new Error("Missing #root element");
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// 1. Host application state
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// These signals are created by the Solid runtime already bundled with the app.
|
|
19
|
+
// Runtime-created modules receive the exact same signal/accessor references.
|
|
20
|
+
|
|
21
|
+
const [hostCount, setHostCount] = Solid.createSignal(100);
|
|
22
|
+
const [hostMessage, setHostMessage] = Solid.createSignal(
|
|
23
|
+
"Hello from the host application",
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// 2. Create the runtime and reuse this application's Solid modules
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// This is important: dynamic components do NOT load another Solid runtime.
|
|
30
|
+
|
|
31
|
+
const runtime = createRuntime({
|
|
32
|
+
modules: {
|
|
33
|
+
"solid-js": Solid,
|
|
34
|
+
"@solidjs/web": SolidWeb,
|
|
35
|
+
"@solidjs/html": { default: html },
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// 3. Expose host-owned state/services as a normal runtime module
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Runtime source can now use:
|
|
43
|
+
//
|
|
44
|
+
// import { hostCount, setHostCount } from "@app/state";
|
|
45
|
+
//
|
|
46
|
+
// No serialization or global-variable rewriting is involved.
|
|
47
|
+
|
|
48
|
+
runtime.defineModule("@app/state", {
|
|
49
|
+
hostCount,
|
|
50
|
+
setHostCount,
|
|
51
|
+
hostMessage,
|
|
52
|
+
setHostMessage,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// 4. Observe runtime module scripts added to the document
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// We already own registration in this demo, so only watch scripts added from
|
|
59
|
+
// this point forward. Each observed batch is fully defined before any entry
|
|
60
|
+
// in that batch executes.
|
|
61
|
+
|
|
62
|
+
const htmlRuntime = createHTMLRuntime(runtime, {
|
|
63
|
+
scope: "main",
|
|
64
|
+
root: document,
|
|
65
|
+
appendTo: document.body,
|
|
66
|
+
acceptUnscoped: false,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await htmlRuntime.observe({
|
|
70
|
+
registerExisting: false,
|
|
71
|
+
onError(error) {
|
|
72
|
+
console.error("Observed runtime module failed", error);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// This script is inert to the browser because its type is solid-jsx, but the
|
|
77
|
+
// solid-tag-runtime HTML adapter discovers it through MutationObserver.
|
|
78
|
+
const observedModuleScript = document.createElement("script");
|
|
79
|
+
observedModuleScript.type = "solid-jsx";
|
|
80
|
+
observedModuleScript.setAttribute("data-solid-runtime", "main");
|
|
81
|
+
observedModuleScript.setAttribute("module", "/observed/Badge.jsx");
|
|
82
|
+
observedModuleScript.textContent = `
|
|
83
|
+
export function ObservedBadge(props) {
|
|
84
|
+
return (
|
|
85
|
+
<small
|
|
86
|
+
style={{
|
|
87
|
+
display: "inline-block",
|
|
88
|
+
padding: "4px 8px",
|
|
89
|
+
border: "1px dashed #777",
|
|
90
|
+
"border-radius": "999px"
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
Observed module: {props.children}
|
|
94
|
+
</small>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
document.body.append(observedModuleScript);
|
|
99
|
+
|
|
100
|
+
// MutationObserver is automatic; flush() is useful when the application wants
|
|
101
|
+
// to explicitly wait until discovered modules are ready before importing them.
|
|
102
|
+
await htmlRuntime.flush();
|
|
103
|
+
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// 5. Define a reusable runtime JSX module
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
runtime.define(
|
|
109
|
+
"/ui/Button.jsx",
|
|
110
|
+
`
|
|
111
|
+
export function Button(props) {
|
|
112
|
+
return (
|
|
113
|
+
<button
|
|
114
|
+
type="button"
|
|
115
|
+
onClick={props.onClick}
|
|
116
|
+
style={{
|
|
117
|
+
padding: "8px 12px",
|
|
118
|
+
border: "1px solid #777",
|
|
119
|
+
"border-radius": "6px",
|
|
120
|
+
cursor: "pointer"
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
{props.children}
|
|
124
|
+
</button>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
`,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// 6. Define another runtime module that imports Button + host state + Solid
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
runtime.define(
|
|
135
|
+
"/features/Counter.jsx",
|
|
136
|
+
`
|
|
137
|
+
import { createSignal } from "solid-js";
|
|
138
|
+
import { Button } from "../ui/Button.jsx";
|
|
139
|
+
import { hostCount, setHostCount } from "@app/state";
|
|
140
|
+
|
|
141
|
+
export function Counter() {
|
|
142
|
+
const [localCount, setLocalCount] = createSignal(0);
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<section
|
|
146
|
+
style={{
|
|
147
|
+
display: "grid",
|
|
148
|
+
gap: "10px",
|
|
149
|
+
padding: "16px",
|
|
150
|
+
border: "1px solid #555",
|
|
151
|
+
"border-radius": "8px"
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
<strong>Runtime Counter module</strong>
|
|
155
|
+
|
|
156
|
+
<div>Local runtime signal: {localCount()}</div>
|
|
157
|
+
<div>Host application signal: {hostCount()}</div>
|
|
158
|
+
|
|
159
|
+
<div style={{ display: "flex", gap: "8px", "flex-wrap": "wrap" }}>
|
|
160
|
+
<Button onClick={() => setLocalCount(value => value + 1)}>
|
|
161
|
+
Increment local
|
|
162
|
+
</Button>
|
|
163
|
+
|
|
164
|
+
<Button onClick={() => setHostCount(value => value + 1)}>
|
|
165
|
+
Increment host
|
|
166
|
+
</Button>
|
|
167
|
+
</div>
|
|
168
|
+
</section>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
`,
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// 7. toModule(): create an anonymous runtime module and get its exports
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
const greetingModule = await runtime.toModule(`
|
|
179
|
+
export function Greeting(props) {
|
|
180
|
+
return (
|
|
181
|
+
<p style={{ margin: 0, opacity: 0.8 }}>
|
|
182
|
+
Runtime module says: Hello {props.name}!
|
|
183
|
+
</p>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
`);
|
|
187
|
+
|
|
188
|
+
// A compiled module namespace can itself be exposed as a named host module.
|
|
189
|
+
// That lets other runtime modules import it normally.
|
|
190
|
+
runtime.defineModule("@runtime/greeting", greetingModule);
|
|
191
|
+
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// 8. Define the runtime application module
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// It imports another runtime JSX module, an anonymous module namespace that we
|
|
196
|
+
// registered above, and host state.
|
|
197
|
+
|
|
198
|
+
runtime.define(
|
|
199
|
+
"/App.jsx",
|
|
200
|
+
`
|
|
201
|
+
import { Counter } from "./features/Counter.jsx";
|
|
202
|
+
import { Greeting } from "@runtime/greeting";
|
|
203
|
+
import { ObservedBadge } from "./observed/Badge.jsx";
|
|
204
|
+
import { hostMessage, setHostMessage } from "@app/state";
|
|
205
|
+
|
|
206
|
+
export function App(props) {
|
|
207
|
+
return (
|
|
208
|
+
<main
|
|
209
|
+
style={{
|
|
210
|
+
display: "grid",
|
|
211
|
+
gap: "16px",
|
|
212
|
+
width: "min(680px, calc(100% - 32px))",
|
|
213
|
+
margin: "40px auto",
|
|
214
|
+
"font-family": "system-ui, sans-serif"
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
<h1 style={{ margin: 0 }}>{props.title}</h1>
|
|
218
|
+
|
|
219
|
+
<Greeting name={props.name} />
|
|
220
|
+
|
|
221
|
+
<ObservedBadge>
|
|
222
|
+
discovered through MutationObserver
|
|
223
|
+
</ObservedBadge>
|
|
224
|
+
|
|
225
|
+
<p style={{ margin: 0 }}>
|
|
226
|
+
Host message: {hostMessage()}
|
|
227
|
+
</p>
|
|
228
|
+
|
|
229
|
+
<button
|
|
230
|
+
type="button"
|
|
231
|
+
onClick={() =>
|
|
232
|
+
setHostMessage("The runtime App changed host-owned state")
|
|
233
|
+
}
|
|
234
|
+
>
|
|
235
|
+
Change host message from runtime code
|
|
236
|
+
</button>
|
|
237
|
+
|
|
238
|
+
<Counter />
|
|
239
|
+
</main>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
`,
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
// 9. Import the runtime module and use its exported component in host JSX
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
|
|
249
|
+
const appModule = await runtime.import("/App.jsx");
|
|
250
|
+
const RuntimeApp = appModule.App as Component<{
|
|
251
|
+
title: string;
|
|
252
|
+
name: string;
|
|
253
|
+
}>;
|
|
254
|
+
|
|
255
|
+
const disposeRender = render(
|
|
256
|
+
() => (
|
|
257
|
+
<RuntimeApp
|
|
258
|
+
title="solid-tag-runtime demo"
|
|
259
|
+
name="Solid"
|
|
260
|
+
/>
|
|
261
|
+
),
|
|
262
|
+
root,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
// 10. Runtime module graph introspection
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
|
|
269
|
+
console.table(runtime.modules());
|
|
270
|
+
console.log("/App.jsx dependencies:", runtime.dependencies("/App.jsx"));
|
|
271
|
+
console.log(
|
|
272
|
+
"/features/Counter.jsx dependencies:",
|
|
273
|
+
runtime.dependencies("/features/Counter.jsx"),
|
|
274
|
+
);
|
|
275
|
+
console.log(
|
|
276
|
+
"/ui/Button.jsx dependents:",
|
|
277
|
+
runtime.dependents("/ui/Button.jsx"),
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// You can inspect the transformed module source too.
|
|
281
|
+
const compiledCounter = await runtime.compile("/features/Counter.jsx");
|
|
282
|
+
console.log("Compiled Counter module:\n", compiledCounter.code);
|
|
283
|
+
|
|
284
|
+
// Optional demo/debug handle from the browser console.
|
|
285
|
+
Object.assign(globalThis, {
|
|
286
|
+
solidTagDemo: {
|
|
287
|
+
runtime,
|
|
288
|
+
hostCount,
|
|
289
|
+
setHostCount,
|
|
290
|
+
hostMessage,
|
|
291
|
+
setHostMessage,
|
|
292
|
+
htmlRuntime,
|
|
293
|
+
dispose() {
|
|
294
|
+
htmlRuntime.disconnect();
|
|
295
|
+
observedModuleScript.remove();
|
|
296
|
+
disposeRender();
|
|
297
|
+
runtime.dispose();
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
main().catch(error => {
|
|
304
|
+
console.error("solid-tag-runtime demo failed", error);
|
|
305
|
+
|
|
306
|
+
const root = document.getElementById("root");
|
|
307
|
+
if (root) {
|
|
308
|
+
const pre = document.createElement("pre");
|
|
309
|
+
pre.style.whiteSpace = "pre-wrap";
|
|
310
|
+
pre.style.color = "crimson";
|
|
311
|
+
pre.textContent =
|
|
312
|
+
error instanceof Error
|
|
313
|
+
? error.stack ?? error.message
|
|
314
|
+
: String(error);
|
|
315
|
+
|
|
316
|
+
root.replaceChildren(pre);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>solid-tag-runtime rendering</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<div id="app"></div>
|
|
9
|
+
|
|
10
|
+
<!-- Define a reusable runtime module. -->
|
|
11
|
+
<script type="solid-jsx" data-solid-runtime="main" module="/Counter.jsx">
|
|
12
|
+
import { createSignal } from "solid-js";
|
|
13
|
+
|
|
14
|
+
export default function Counter(props) {
|
|
15
|
+
const [count, setCount] = createSignal(0);
|
|
16
|
+
return (
|
|
17
|
+
<button onClick={() => setCount(value => value + 1)}>
|
|
18
|
+
{props.label}: {count()}
|
|
19
|
+
</button>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<!-- Define + mount one declaration-owned instance into #app. -->
|
|
25
|
+
<script
|
|
26
|
+
type="solid-jsx"
|
|
27
|
+
data-solid-runtime="main"
|
|
28
|
+
module="/App.jsx"
|
|
29
|
+
render="#app"
|
|
30
|
+
>
|
|
31
|
+
export default function App() {
|
|
32
|
+
return <h1>Mounted by <script render></h1>;
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<!-- Reference the already-defined Counter module and create independent instances. -->
|
|
37
|
+
<solid-render
|
|
38
|
+
data-solid-runtime="main"
|
|
39
|
+
module="/Counter.jsx"
|
|
40
|
+
prop:label="Counter A"
|
|
41
|
+
></solid-render>
|
|
42
|
+
|
|
43
|
+
<solid-render
|
|
44
|
+
data-solid-runtime="main"
|
|
45
|
+
module="/Counter.jsx"
|
|
46
|
+
prop:label="Counter B"
|
|
47
|
+
></solid-render>
|
|
48
|
+
|
|
49
|
+
<!--
|
|
50
|
+
This bootstrap is ordinary JavaScript. The surrounding application/import
|
|
51
|
+
map is responsible for resolving Solid and solid-tag-runtime bare imports.
|
|
52
|
+
-->
|
|
53
|
+
<script type="module">
|
|
54
|
+
import * as Solid from "solid-js";
|
|
55
|
+
import * as SolidWeb from "@solidjs/web";
|
|
56
|
+
import html from "@solidjs/html";
|
|
57
|
+
import { createRuntime } from "solid-tag-runtime";
|
|
58
|
+
import { createHTMLRuntime } from "solid-tag-runtime/html";
|
|
59
|
+
|
|
60
|
+
const runtime = createRuntime({
|
|
61
|
+
modules: {
|
|
62
|
+
"solid-js": Solid,
|
|
63
|
+
"@solidjs/web": SolidWeb,
|
|
64
|
+
"@solidjs/html": { default: html },
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const htmlRuntime = createHTMLRuntime(runtime, {
|
|
69
|
+
scope: "main",
|
|
70
|
+
root: document,
|
|
71
|
+
appendTo: document.body,
|
|
72
|
+
acceptUnscoped: false,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await htmlRuntime.register();
|
|
76
|
+
await htmlRuntime.observe({ registerExisting: false });
|
|
77
|
+
</script>
|
|
78
|
+
</body>
|
|
79
|
+
</html>
|
package/index.d.ts
CHANGED
|
@@ -1,30 +1,58 @@
|
|
|
1
1
|
export type ModuleFormat = "jsx" | "js";
|
|
2
|
+
export type CompileCacheMode = "use" | "refresh" | "bypass";
|
|
2
3
|
|
|
3
4
|
export interface ModuleNamespaceLike {
|
|
4
5
|
readonly [key: string]: unknown;
|
|
5
6
|
}
|
|
6
7
|
|
|
8
|
+
export interface CompileContext {
|
|
9
|
+
id?: string;
|
|
10
|
+
format?: ModuleFormat;
|
|
11
|
+
}
|
|
12
|
+
|
|
7
13
|
export interface CompilerImportReference {
|
|
8
14
|
specifier: string;
|
|
9
15
|
start: number;
|
|
10
16
|
end: number;
|
|
11
|
-
kind?: string;
|
|
17
|
+
kind?: "static" | "dynamic" | "export" | string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CompiledArtifact {
|
|
21
|
+
schema?: number;
|
|
22
|
+
code: string;
|
|
23
|
+
imports: CompilerImportReference[];
|
|
24
|
+
diagnostics?: unknown[];
|
|
25
|
+
sourceMap?: string;
|
|
26
|
+
changed?: boolean;
|
|
12
27
|
}
|
|
13
28
|
|
|
14
29
|
export interface RuntimeCompiler {
|
|
15
|
-
|
|
30
|
+
/** Stable identity required for persistent compile-cache reuse. */
|
|
31
|
+
fingerprint?: string | ((context: CompileContext) => string | Promise<string>);
|
|
32
|
+
/** Additional compile-affecting context to include in persistent cache identity. */
|
|
33
|
+
cacheContext?: (context: CompileContext) => unknown | Promise<unknown>;
|
|
34
|
+
/** Preferred compiler boundary: return a linker-ready pre-link artifact. */
|
|
35
|
+
compile?(source: string, context?: CompileContext): CompiledArtifact | Promise<CompiledArtifact>;
|
|
36
|
+
/** Transitional compiler API retained for compatibility. */
|
|
37
|
+
analyze?(source: string, context?: CompileContext): {
|
|
38
|
+
imports?: CompilerImportReference[];
|
|
39
|
+
needsHtmlRuntime?: boolean;
|
|
40
|
+
} | Promise<{
|
|
16
41
|
imports?: CompilerImportReference[];
|
|
17
42
|
needsHtmlRuntime?: boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
43
|
+
}>;
|
|
44
|
+
/** Transitional compiler API retained for compatibility. */
|
|
45
|
+
transform?(source: string, context?: CompileContext & { htmlImportSource?: string }): {
|
|
46
|
+
code: string;
|
|
47
|
+
diagnostics?: unknown[];
|
|
48
|
+
changed?: boolean;
|
|
49
|
+
sourceMap?: string;
|
|
50
|
+
} | Promise<{
|
|
24
51
|
code: string;
|
|
25
52
|
diagnostics?: unknown[];
|
|
26
53
|
changed?: boolean;
|
|
27
|
-
|
|
54
|
+
sourceMap?: string;
|
|
55
|
+
}>;
|
|
28
56
|
}
|
|
29
57
|
|
|
30
58
|
export interface ModuleUrlBackend {
|
|
@@ -33,6 +61,53 @@ export interface ModuleUrlBackend {
|
|
|
33
61
|
revoke?(url: string): void;
|
|
34
62
|
}
|
|
35
63
|
|
|
64
|
+
export interface CachedCompileRecord {
|
|
65
|
+
schema: number;
|
|
66
|
+
key: string;
|
|
67
|
+
artifactAbi: string;
|
|
68
|
+
sourceHash: string;
|
|
69
|
+
format: string;
|
|
70
|
+
compilerFingerprint: string;
|
|
71
|
+
compileContextHash: string;
|
|
72
|
+
artifact: CompiledArtifact;
|
|
73
|
+
createdAt: number;
|
|
74
|
+
lastUsedAt?: number;
|
|
75
|
+
byteSize?: number;
|
|
76
|
+
artifactHash?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface CompileCacheStore {
|
|
80
|
+
readonly kind?: string;
|
|
81
|
+
get(key: string): Promise<CachedCompileRecord | undefined>;
|
|
82
|
+
set(key: string, value: CachedCompileRecord): Promise<void>;
|
|
83
|
+
delete(key: string): Promise<boolean | void>;
|
|
84
|
+
clear?(options?: { prefix?: string }): Promise<number | void>;
|
|
85
|
+
entries?(options?: { prefix?: string }): Promise<Array<[string, CachedCompileRecord]>>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface CompileCacheOptions {
|
|
89
|
+
enabled?: boolean;
|
|
90
|
+
store: CompileCacheStore;
|
|
91
|
+
namespace?: string;
|
|
92
|
+
version?: string;
|
|
93
|
+
maxEntries?: number;
|
|
94
|
+
maxBytes?: number;
|
|
95
|
+
/** Maximum record age in milliseconds. */
|
|
96
|
+
maxAge?: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface LocalStorageLike {
|
|
100
|
+
readonly length: number;
|
|
101
|
+
key(index: number): string | null;
|
|
102
|
+
getItem(key: string): string | null;
|
|
103
|
+
setItem(key: string, value: string): void;
|
|
104
|
+
removeItem(key: string): void;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface IndexedDBFactoryLike {
|
|
108
|
+
open(name: string, version?: number): any;
|
|
109
|
+
}
|
|
110
|
+
|
|
36
111
|
export interface RuntimeOptions {
|
|
37
112
|
compiler?: RuntimeCompiler;
|
|
38
113
|
compilerOptions?: Record<string, unknown>;
|
|
@@ -41,6 +116,8 @@ export interface RuntimeOptions {
|
|
|
41
116
|
allowNativeImports?: boolean;
|
|
42
117
|
resolve?: (specifier: string, importer: string | null, runtime: SolidTagRuntime) => string | void;
|
|
43
118
|
moduleUrlBackend?: ModuleUrlBackend;
|
|
119
|
+
/** Opt-in persistent pre-link compile artifact cache. */
|
|
120
|
+
compileCache?: CompileCacheOptions | false;
|
|
44
121
|
}
|
|
45
122
|
|
|
46
123
|
export interface DefineOptions {
|
|
@@ -55,6 +132,20 @@ export interface ToComponentOptions extends ToModuleOptions {
|
|
|
55
132
|
exportName?: string;
|
|
56
133
|
}
|
|
57
134
|
|
|
135
|
+
export interface CompileOptions {
|
|
136
|
+
cache?: CompileCacheMode;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface CompileCacheInfo {
|
|
140
|
+
enabled: boolean;
|
|
141
|
+
status: "none" | "hit" | "miss" | "refresh" | "bypass";
|
|
142
|
+
source?: string;
|
|
143
|
+
key?: string;
|
|
144
|
+
compilerFingerprint?: string;
|
|
145
|
+
sourceHash?: string;
|
|
146
|
+
compileContextHash?: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
58
149
|
export interface ModuleInfo {
|
|
59
150
|
id: string;
|
|
60
151
|
kind: "source" | "host" | "url";
|
|
@@ -65,6 +156,7 @@ export interface ModuleInfo {
|
|
|
65
156
|
dependents: string[];
|
|
66
157
|
url?: string;
|
|
67
158
|
diagnostics: unknown[];
|
|
159
|
+
compileCache?: CompileCacheInfo;
|
|
68
160
|
}
|
|
69
161
|
|
|
70
162
|
export interface CompileResult {
|
|
@@ -91,6 +183,23 @@ export interface ClearRuntimeOptions {
|
|
|
91
183
|
preserveHostModules?: boolean;
|
|
92
184
|
}
|
|
93
185
|
|
|
186
|
+
export interface InvalidateOptions {
|
|
187
|
+
dependents?: boolean;
|
|
188
|
+
/** Force only the requested source module to compile fresh on its next link. */
|
|
189
|
+
compile?: boolean;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface RuntimeCompileCache {
|
|
193
|
+
readonly enabled: boolean;
|
|
194
|
+
readonly namespace?: string;
|
|
195
|
+
readonly version?: string;
|
|
196
|
+
readonly store?: string;
|
|
197
|
+
/** Delete the current module's stored compiler artifact without graph invalidation. */
|
|
198
|
+
invalidate(id: string): Promise<boolean>;
|
|
199
|
+
/** Clear current namespace/version, or all versions within the current namespace. */
|
|
200
|
+
clear(options?: { allVersions?: boolean }): Promise<number>;
|
|
201
|
+
}
|
|
202
|
+
|
|
94
203
|
export type ModuleResolutionKind =
|
|
95
204
|
| "custom"
|
|
96
205
|
| "registered"
|
|
@@ -113,28 +222,57 @@ export interface LinkedDependency {
|
|
|
113
222
|
resolvedId: string;
|
|
114
223
|
}
|
|
115
224
|
|
|
225
|
+
export type CompileCacheErrorOperation =
|
|
226
|
+
| "identity"
|
|
227
|
+
| "fingerprint"
|
|
228
|
+
| "read"
|
|
229
|
+
| "write"
|
|
230
|
+
| "delete"
|
|
231
|
+
| "clear"
|
|
232
|
+
| "prune";
|
|
233
|
+
|
|
234
|
+
interface RuntimeEventBase {
|
|
235
|
+
runtimeId: string;
|
|
236
|
+
timestamp: number;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
interface CompileCacheEventBase extends RuntimeEventBase {
|
|
240
|
+
id?: string;
|
|
241
|
+
key?: string;
|
|
242
|
+
store?: string;
|
|
243
|
+
source?: string;
|
|
244
|
+
durationMs?: number;
|
|
245
|
+
byteSize?: number;
|
|
246
|
+
}
|
|
247
|
+
|
|
116
248
|
export type RuntimeLifecycleEvent =
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
249
|
+
| (RuntimeEventBase & { type: "module-defined"; id: string; kind: ModuleInfo["kind"]; version: number; operation: "define" | "defineMany" | "update" | "defineModule" | "defineUrl"; replaced: boolean; module: ModuleInfo })
|
|
250
|
+
| (RuntimeEventBase & { type: "module-updated"; id: string; kind: ModuleInfo["kind"]; previousVersion: number; version: number; format?: ModuleFormat; module: ModuleInfo })
|
|
251
|
+
| (RuntimeEventBase & { type: "modules-defined"; ids: string[]; modules: ModuleInfo[] })
|
|
252
|
+
| (RuntimeEventBase & { type: "module-resolving"; specifier: string; importer: string | null })
|
|
253
|
+
| (RuntimeEventBase & { type: "module-resolved"; specifier: string; importer: string | null; resolvedId: string; resolutionKind: ModuleResolutionKind })
|
|
254
|
+
| (RuntimeEventBase & { type: "module-linking"; id: string; kind: ModuleInfo["kind"]; version: number })
|
|
255
|
+
| (RuntimeEventBase & { type: "module-linked"; id: string; kind: ModuleInfo["kind"]; version: number; dependencies: LinkedDependency[]; module: ModuleInfo })
|
|
256
|
+
| (RuntimeEventBase & { type: "module-invalidated"; id: string; kind: ModuleInfo["kind"]; version: number; reason: string })
|
|
257
|
+
| (RuntimeEventBase & { type: "module-compiled"; id: string; kind: ModuleInfo["kind"]; version: number; module: ModuleInfo })
|
|
258
|
+
| (RuntimeEventBase & { type: "module-evaluating"; id: string; kind: ModuleInfo["kind"]; version: number })
|
|
259
|
+
| (RuntimeEventBase & { type: "module-evaluated"; id: string; kind: ModuleInfo["kind"]; version: number; module: ModuleInfo })
|
|
260
|
+
| (RuntimeEventBase & { type: "module-removed"; id: string; kind: ModuleInfo["kind"]; version: number; invalidateDependents: boolean })
|
|
261
|
+
| (RuntimeEventBase & { type: "module-error"; id?: string; kind?: ModuleInfo["kind"]; version?: number; phase: ModuleErrorPhase; error: unknown })
|
|
262
|
+
| (RuntimeEventBase & { type: "runtime-cleared"; ids: string[]; preserveHostModules: boolean })
|
|
263
|
+
| (RuntimeEventBase & { type: "runtime-disposed" })
|
|
264
|
+
| (CompileCacheEventBase & { type: "compile-cache-hit" })
|
|
265
|
+
| (CompileCacheEventBase & { type: "compile-cache-miss" })
|
|
266
|
+
| (CompileCacheEventBase & { type: "compile-cache-write" })
|
|
267
|
+
| (CompileCacheEventBase & { type: "compile-cache-refresh" })
|
|
268
|
+
| (CompileCacheEventBase & { type: "compile-cache-bypass"; reason?: "requested" | "missing-compiler-fingerprint" | string })
|
|
269
|
+
| (CompileCacheEventBase & { type: "compile-cache-evict"; reason: "maxAge" | "maxEntries" | "maxBytes" | "invalid" | string })
|
|
270
|
+
| (CompileCacheEventBase & { type: "compile-cache-error"; operation: CompileCacheErrorOperation | string; error: unknown });
|
|
132
271
|
|
|
133
272
|
export type RuntimeLifecycleEventType = RuntimeLifecycleEvent["type"];
|
|
134
273
|
export type RuntimeLifecycleEventOfType<T extends RuntimeLifecycleEventType> =
|
|
135
274
|
Extract<RuntimeLifecycleEvent, { type: T }>;
|
|
136
275
|
|
|
137
|
-
|
|
138
276
|
export interface SolidTagRuntime {
|
|
139
277
|
define(id: string, source: string, options?: DefineOptions): string;
|
|
140
278
|
defineMany(definitions: SourceModuleDefinition[]): string[];
|
|
@@ -142,13 +280,15 @@ export interface SolidTagRuntime {
|
|
|
142
280
|
defineModule(id: string, namespace: ModuleNamespaceLike | Function): string;
|
|
143
281
|
defineUrl(id: string, url: string): string;
|
|
144
282
|
import(id: string): Promise<ModuleNamespaceLike>;
|
|
145
|
-
|
|
283
|
+
/** Returns the current linked/executable representation; cache controls affect compiler artifact lookup only. */
|
|
284
|
+
compile(id: string, options?: CompileOptions): Promise<CompileResult>;
|
|
146
285
|
toModule(source: string, options?: ToModuleOptions): Promise<ModuleNamespaceLike>;
|
|
147
286
|
toComponent<T extends Function = Function>(source: string, options?: ToComponentOptions): Promise<T>;
|
|
148
287
|
has(id: string): boolean;
|
|
149
|
-
invalidate(id: string, options?:
|
|
288
|
+
invalidate(id: string, options?: InvalidateOptions): string[];
|
|
150
289
|
remove(id: string, options?: RemoveModuleOptions): boolean;
|
|
151
290
|
clear(options?: ClearRuntimeOptions): string[];
|
|
291
|
+
readonly compileCache: RuntimeCompileCache;
|
|
152
292
|
subscribe(listener: (event: RuntimeLifecycleEvent) => void): () => boolean;
|
|
153
293
|
subscribe<T extends RuntimeLifecycleEventType>(
|
|
154
294
|
type: T,
|
|
@@ -173,6 +313,22 @@ export declare function createSolidTagCompiler(options?: {
|
|
|
173
313
|
transformOptions?: Record<string, unknown>;
|
|
174
314
|
}): RuntimeCompiler;
|
|
175
315
|
|
|
316
|
+
export declare function createMemoryCompileCache(options?: {
|
|
317
|
+
records?: Map<string, CachedCompileRecord>;
|
|
318
|
+
}): CompileCacheStore;
|
|
319
|
+
|
|
320
|
+
export declare function createLocalStorageCompileCache(options?: {
|
|
321
|
+
storage?: LocalStorageLike;
|
|
322
|
+
prefix?: string;
|
|
323
|
+
}): CompileCacheStore;
|
|
324
|
+
|
|
325
|
+
export declare function createIndexedDBCompileCache(options?: {
|
|
326
|
+
database?: string;
|
|
327
|
+
storeName?: string;
|
|
328
|
+
databaseVersion?: number;
|
|
329
|
+
indexedDB?: IndexedDBFactoryLike;
|
|
330
|
+
}): CompileCacheStore;
|
|
331
|
+
|
|
176
332
|
export declare function createDefaultModuleUrlBackend(): ModuleUrlBackend;
|
|
177
333
|
export declare function createBlobModuleUrlBackend(): ModuleUrlBackend;
|
|
178
334
|
export declare function createDataModuleUrlBackend(): ModuleUrlBackend;
|