solid-tag-runtime 0.0.11 → 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 +167 -38
- package/README.md +76 -885
- 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/html.js +191 -19
- package/src/index.js +6 -0
- package/src/runtime.js +656 -74
package/docs/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# solid-tag-runtime documentation
|
|
2
|
+
|
|
3
|
+
`solid-tag-runtime` is a runtime module system for dynamically defined Solid JSX/JavaScript modules. The core package remains module-first and DOM-independent; browser/DOM behavior lives in `solid-tag-runtime/html`.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
- [Getting started](./getting-started.md)
|
|
8
|
+
- [Runtime modules and resolution](./modules.md)
|
|
9
|
+
- [HTML runtime and ownership](./html-runtime.md)
|
|
10
|
+
- [Declarative rendering](./rendering.md)
|
|
11
|
+
- [`<solid-render>`](./solid-render.md)
|
|
12
|
+
- [Lifecycle events](./lifecycle-events.md)
|
|
13
|
+
- [Persistent compile cache](./compile-cache.md)
|
|
14
|
+
|
|
15
|
+
## API reference
|
|
16
|
+
|
|
17
|
+
- [Core runtime API](./api/runtime.md)
|
|
18
|
+
- [HTML runtime API](./api/html.md)
|
|
19
|
+
- [Compile-cache API](./api/compile-cache.md)
|
|
20
|
+
|
|
21
|
+
## Engineering design
|
|
22
|
+
|
|
23
|
+
The root [`ARCHITECTURE.md`](../ARCHITECTURE.md) is the engineering handoff and decision log. It documents internal invariants, compiler/linker boundaries, ownership rules, and compatibility decisions.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Compile-cache API
|
|
2
|
+
|
|
3
|
+
## Providers
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import {
|
|
7
|
+
createMemoryCompileCache,
|
|
8
|
+
createLocalStorageCompileCache,
|
|
9
|
+
createIndexedDBCompileCache,
|
|
10
|
+
} from "solid-tag-runtime";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Memory
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const store = createMemoryCompileCache();
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### localStorage
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const store = createLocalStorageCompileCache({
|
|
23
|
+
prefix: "solid-tag-runtime:compile-cache:",
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### IndexedDB
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const store = createIndexedDBCompileCache({
|
|
31
|
+
database: "my-app-runtime",
|
|
32
|
+
storeName: "artifacts",
|
|
33
|
+
databaseVersion: 1,
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Runtime configuration
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const runtime = createRuntime({
|
|
41
|
+
compileCache: {
|
|
42
|
+
store,
|
|
43
|
+
namespace: "main",
|
|
44
|
+
version: "1",
|
|
45
|
+
maxEntries: 500,
|
|
46
|
+
maxBytes: 50 * 1024 * 1024,
|
|
47
|
+
maxAge: 30 * 24 * 60 * 60 * 1000,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Store contract
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
interface CompileCacheStore {
|
|
56
|
+
kind?: string;
|
|
57
|
+
|
|
58
|
+
get(key): Promise<CachedCompileRecord | undefined>;
|
|
59
|
+
set(key, record): Promise<void>;
|
|
60
|
+
delete(key): Promise<boolean | void>;
|
|
61
|
+
|
|
62
|
+
clear?({ prefix? }): Promise<number | void>;
|
|
63
|
+
entries?({ prefix? }): Promise<Array<[string, CachedCompileRecord]>>;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`clear()` and `entries()` are used by namespace/version management and built-in pruning. Custom stores that omit them can still serve normal lookup/write/delete operations, but cache-wide management is limited.
|
|
68
|
+
|
|
69
|
+
## Cache modes
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
await runtime.compile(id, { cache: "use" });
|
|
73
|
+
await runtime.compile(id, { cache: "refresh" });
|
|
74
|
+
await runtime.compile(id, { cache: "bypass" });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Management
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
await runtime.compileCache.invalidate(id);
|
|
81
|
+
await runtime.compileCache.clear();
|
|
82
|
+
await runtime.compileCache.clear({ allVersions: true });
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Events
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
compile-cache-hit
|
|
89
|
+
compile-cache-miss
|
|
90
|
+
compile-cache-write
|
|
91
|
+
compile-cache-refresh
|
|
92
|
+
compile-cache-bypass
|
|
93
|
+
compile-cache-error
|
|
94
|
+
compile-cache-evict
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
All events are observational.
|
|
98
|
+
|
|
99
|
+
## Failure and quota behavior
|
|
100
|
+
|
|
101
|
+
Normal cache lookup/write failures are optimization failures rather than module failures. A quota-style write failure triggers pruning and one write retry before `compile-cache-error` is emitted.
|
|
102
|
+
|
|
103
|
+
Explicit management operations such as `runtime.compileCache.clear()` may reject because the caller explicitly requested the storage mutation.
|
package/docs/api/html.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# HTML runtime API
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import {
|
|
5
|
+
createHTMLRuntime,
|
|
6
|
+
registerHTML,
|
|
7
|
+
observeHTML,
|
|
8
|
+
defineScript,
|
|
9
|
+
registerSolidRenderElement,
|
|
10
|
+
} from "solid-tag-runtime/html";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Controller
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const html = createHTMLRuntime(runtime, options);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Common options:
|
|
20
|
+
|
|
21
|
+
- `scope`
|
|
22
|
+
- `root`
|
|
23
|
+
- `appendTo`
|
|
24
|
+
- `acceptUnscoped`
|
|
25
|
+
- `executeEntries`
|
|
26
|
+
- `executeRenders`
|
|
27
|
+
- `onError`
|
|
28
|
+
|
|
29
|
+
## Discovery and observation
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
await html.register(options?);
|
|
33
|
+
await html.observe(options?);
|
|
34
|
+
await html.flush(options?);
|
|
35
|
+
html.disconnect();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Explicit ownership
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
await html.registerElement(element, options?);
|
|
42
|
+
await html.append(element, options?);
|
|
43
|
+
await html.addModule(options);
|
|
44
|
+
await html.updateElement(element, options?);
|
|
45
|
+
await html.removeElement(element, options?);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Root/append lifecycle
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
await html.setRoot(root, options?);
|
|
52
|
+
await html.moveTo(root, options?);
|
|
53
|
+
html.setAppendTarget(target);
|
|
54
|
+
|
|
55
|
+
html.root;
|
|
56
|
+
html.appendTarget;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Introspection
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
html.owns(element);
|
|
63
|
+
html.getModuleId(element);
|
|
64
|
+
html.getElement(moduleId);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Events
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
html.subscribe(listener);
|
|
71
|
+
html.subscribe(type, listener);
|
|
72
|
+
html.subscribe(types, listener);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Convenience functions
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
await registerHTML(runtime, options?);
|
|
79
|
+
await defineScript(runtime, element, options?);
|
|
80
|
+
const observer = await observeHTML(runtime, options?);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For rendering semantics see [Declarative rendering](../rendering.md) and [`<solid-render>`](../solid-render.md).
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Core runtime API
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import { createRuntime } from "solid-tag-runtime";
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
## Creation
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const runtime = createRuntime(options);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Important options:
|
|
14
|
+
|
|
15
|
+
- `modules` — initial host namespace modules
|
|
16
|
+
- `urls` — initial URL modules
|
|
17
|
+
- `compiler` / `compilerOptions`
|
|
18
|
+
- `resolve`
|
|
19
|
+
- `allowNativeImports`
|
|
20
|
+
- `moduleUrlBackend`
|
|
21
|
+
- `compileCache` — optional persistent pre-link compiler cache
|
|
22
|
+
|
|
23
|
+
## Definition
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
runtime.define(id, source, options?);
|
|
27
|
+
runtime.defineMany(definitions);
|
|
28
|
+
runtime.defineModule(id, namespace);
|
|
29
|
+
runtime.defineUrl(id, url);
|
|
30
|
+
runtime.update(id, source, options?);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Loading/compilation
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
await runtime.import(id);
|
|
37
|
+
await runtime.compile(id, { cache?: "use" | "refresh" | "bypass" });
|
|
38
|
+
await runtime.toModule(source, options?);
|
|
39
|
+
await runtime.toComponent(source, options?);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`runtime.compile()` preserves its public meaning: it returns the current linked/executable code and URL. The persistent cache stores an internal pre-link artifact instead.
|
|
43
|
+
|
|
44
|
+
## Lifecycle
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
runtime.invalidate(id, {
|
|
48
|
+
dependents?: boolean,
|
|
49
|
+
compile?: boolean,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
runtime.remove(id, options?);
|
|
53
|
+
runtime.clear(options?);
|
|
54
|
+
runtime.dispose();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Introspection
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
runtime.has(id);
|
|
61
|
+
runtime.resolve(specifier, importer?);
|
|
62
|
+
runtime.modules();
|
|
63
|
+
runtime.dependencies(id);
|
|
64
|
+
runtime.dependents(id);
|
|
65
|
+
runtime.getModuleInfo(id);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Events
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
runtime.subscribe(listener);
|
|
72
|
+
runtime.subscribe(type, listener);
|
|
73
|
+
runtime.subscribe(types, listener);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
See [Lifecycle events](../lifecycle-events.md).
|
|
77
|
+
|
|
78
|
+
## Compile-cache management
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
runtime.compileCache.enabled;
|
|
82
|
+
await runtime.compileCache.invalidate(id);
|
|
83
|
+
await runtime.compileCache.clear();
|
|
84
|
+
await runtime.compileCache.clear({ allVersions: true });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See [Compile-cache API](./compile-cache.md).
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Persistent compile cache
|
|
2
|
+
|
|
3
|
+
Persistent compile caching is opt-in. It stores **pre-link compiled artifacts**, not linked runtime modules.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
source
|
|
7
|
+
↓
|
|
8
|
+
compile
|
|
9
|
+
↓
|
|
10
|
+
compiled artifact ← persistent cache boundary
|
|
11
|
+
↓
|
|
12
|
+
link
|
|
13
|
+
↓
|
|
14
|
+
module URL
|
|
15
|
+
↓
|
|
16
|
+
native import/evaluation
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The cache accelerates parsing/transformation/module-reference analysis while all runtime-dependent linking stays fresh.
|
|
20
|
+
|
|
21
|
+
## What is persisted
|
|
22
|
+
|
|
23
|
+
A compiled artifact contains linker-ready JavaScript and import-reference metadata:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
{
|
|
27
|
+
code,
|
|
28
|
+
imports,
|
|
29
|
+
diagnostics,
|
|
30
|
+
sourceMap?
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Import metadata refers to the **compiled code**, not the original JSX source.
|
|
35
|
+
|
|
36
|
+
## What is never persisted
|
|
37
|
+
|
|
38
|
+
- linked source containing current Blob/data/dependency URLs
|
|
39
|
+
- Blob/data URLs
|
|
40
|
+
- module URL backend results
|
|
41
|
+
- host bridge identities
|
|
42
|
+
- native module namespaces
|
|
43
|
+
- import promises
|
|
44
|
+
- runtime resolver output
|
|
45
|
+
|
|
46
|
+
## Enable IndexedDB caching
|
|
47
|
+
|
|
48
|
+
IndexedDB is the recommended browser backend:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import {
|
|
52
|
+
createRuntime,
|
|
53
|
+
createIndexedDBCompileCache,
|
|
54
|
+
} from "solid-tag-runtime";
|
|
55
|
+
|
|
56
|
+
const runtime = createRuntime({
|
|
57
|
+
compileCache: {
|
|
58
|
+
store: createIndexedDBCompileCache({
|
|
59
|
+
database: "my-app-runtime",
|
|
60
|
+
}),
|
|
61
|
+
namespace: "main",
|
|
62
|
+
version: "1",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Without `compileCache`, persistent lookup/write behavior is disabled.
|
|
68
|
+
|
|
69
|
+
## localStorage
|
|
70
|
+
|
|
71
|
+
Useful for small demos and debugging:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createLocalStorageCompileCache } from "solid-tag-runtime";
|
|
75
|
+
|
|
76
|
+
const store = createLocalStorageCompileCache();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`localStorage` is synchronous underneath, smaller, and less suitable for large compiled artifacts. The provider still exposes the same async store interface.
|
|
80
|
+
|
|
81
|
+
## Memory provider
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { createMemoryCompileCache } from "solid-tag-runtime";
|
|
85
|
+
|
|
86
|
+
const store = createMemoryCompileCache();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This is useful for tests, benchmarks, and validating cache identity across runtime instances within one page/process.
|
|
90
|
+
|
|
91
|
+
## Cache identity
|
|
92
|
+
|
|
93
|
+
The logical artifact key includes:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
artifact ABI
|
|
97
|
+
+ compiler fingerprint
|
|
98
|
+
+ source format
|
|
99
|
+
+ compile-affecting context
|
|
100
|
+
+ exact source SHA-256
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
It deliberately excludes:
|
|
104
|
+
|
|
105
|
+
- dependency versions/source
|
|
106
|
+
- resolver state
|
|
107
|
+
- module URL backend
|
|
108
|
+
- host-module values
|
|
109
|
+
- module ID by default
|
|
110
|
+
|
|
111
|
+
Therefore identical source may share one compiler artifact under different module IDs while linking relative imports independently for each ID.
|
|
112
|
+
|
|
113
|
+
## Compiler fingerprint
|
|
114
|
+
|
|
115
|
+
The default `solid-tag` compiler supplies a stable fingerprint. A custom compiler must provide one to use persistent storage safely:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const compiler = {
|
|
119
|
+
fingerprint: "my-compiler:v3",
|
|
120
|
+
compile(source, context) {
|
|
121
|
+
return artifact;
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The fingerprint may be a function when compilation behavior depends on context:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
fingerprint(context) {
|
|
130
|
+
return `my-compiler:v3:${context.format}`;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
A custom compiler without a stable fingerprint still compiles normally, but persistent caching is bypassed and a one-time warning/event is produced.
|
|
135
|
+
|
|
136
|
+
## `use`, `refresh`, and `bypass`
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
await runtime.compile("/App.jsx", { cache: "use" });
|
|
140
|
+
await runtime.compile("/App.jsx", { cache: "refresh" });
|
|
141
|
+
await runtime.compile("/App.jsx", { cache: "bypass" });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### `use`
|
|
145
|
+
|
|
146
|
+
Read reusable compiler artifacts; compile/write on miss.
|
|
147
|
+
|
|
148
|
+
### `refresh`
|
|
149
|
+
|
|
150
|
+
Skip reusable artifact reads for the requested module, compile fresh, and replace the stored record.
|
|
151
|
+
|
|
152
|
+
### `bypass`
|
|
153
|
+
|
|
154
|
+
Compile the requested module fresh without persistent read/write.
|
|
155
|
+
|
|
156
|
+
Dependencies continue using their normal reusable artifacts.
|
|
157
|
+
|
|
158
|
+
## Graph invalidation vs compiler invalidation
|
|
159
|
+
|
|
160
|
+
Normal invalidation preserves compiler artifacts:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
runtime.invalidate("/Button.jsx");
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
This revokes/rebuilds linked/evaluated graph state but keeps syntax work reusable.
|
|
167
|
+
|
|
168
|
+
Force only the requested module to compile fresh next time:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
runtime.invalidate("/Button.jsx", {
|
|
172
|
+
compile: true,
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Dependents relink but are not forced to recompile.
|
|
177
|
+
|
|
178
|
+
## Persistent cache management
|
|
179
|
+
|
|
180
|
+
Delete the current module's stored artifact:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
await runtime.compileCache.invalidate("/App.jsx");
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Clear the current namespace/version:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
await runtime.compileCache.clear();
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Clear all versions in the current namespace:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
await runtime.compileCache.clear({
|
|
196
|
+
allVersions: true,
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
These are cache-management operations, not graph-removal APIs.
|
|
201
|
+
|
|
202
|
+
## Application version
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
compileCache: {
|
|
206
|
+
namespace: "editor",
|
|
207
|
+
version: "2026.10.3",
|
|
208
|
+
store,
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Changing `version` creates logical misses without requiring an eager database scan/deletion. It is the application-controlled global invalidation switch.
|
|
213
|
+
|
|
214
|
+
## Bounds
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
compileCache: {
|
|
218
|
+
store,
|
|
219
|
+
namespace: "editor",
|
|
220
|
+
version: "1",
|
|
221
|
+
maxEntries: 500,
|
|
222
|
+
maxBytes: 50 * 1024 * 1024,
|
|
223
|
+
maxAge: 30 * 24 * 60 * 60 * 1000,
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Built-in stores support basic age/entry/byte pruning. This is intentionally simple; cross-tab locks and sophisticated global LRU are not part of the first implementation.
|
|
228
|
+
|
|
229
|
+
## Failure behavior
|
|
230
|
+
|
|
231
|
+
Persistent storage is an optimization. Read/write/corruption/provider failures fall back to normal compilation whenever possible and are observable through `compile-cache-error`.
|
|
232
|
+
|
|
233
|
+
For quota-style write failures, the runtime first prunes eligible/older records and retries the write once. If that retry also fails, it emits `compile-cache-error` and continues with the freshly compiled in-memory artifact. Cache failure never makes normal module compilation unavailable.
|
|
234
|
+
|
|
235
|
+
Explicit management calls such as `compileCache.clear()` may reject when the explicitly requested storage operation cannot be completed.
|
|
236
|
+
|
|
237
|
+
## Introspection
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
runtime.getModuleInfo("/App.jsx")?.compileCache;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Example fields:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
{
|
|
247
|
+
enabled: true,
|
|
248
|
+
status: "hit",
|
|
249
|
+
source: "indexeddb",
|
|
250
|
+
key: "...",
|
|
251
|
+
compilerFingerprint: "...",
|
|
252
|
+
sourceHash: "...",
|
|
253
|
+
compileContextHash: "..."
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Dependency-only changes
|
|
258
|
+
|
|
259
|
+
If `/App.jsx` imports `/Button.jsx` and only `Button` source changes:
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
Button
|
|
263
|
+
→ compiler miss/new artifact
|
|
264
|
+
→ relink
|
|
265
|
+
|
|
266
|
+
App
|
|
267
|
+
→ compiler artifact reused
|
|
268
|
+
→ relink against new Button URL
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
This is the primary reason the persistent cache boundary is pre-link rather than linked output.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install solid-tag-runtime solid-tag
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The runtime intentionally does not bundle its own Solid runtime. Register the host application's existing Solid modules so dynamically compiled code shares the same reactive system.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import * as Solid from "solid-js";
|
|
13
|
+
import * as SolidWeb from "@solidjs/web";
|
|
14
|
+
import html from "@solidjs/html";
|
|
15
|
+
import { createRuntime } from "solid-tag-runtime";
|
|
16
|
+
|
|
17
|
+
const runtime = createRuntime({
|
|
18
|
+
modules: {
|
|
19
|
+
"solid-js": Solid,
|
|
20
|
+
"@solidjs/web": SolidWeb,
|
|
21
|
+
"@solidjs/html": { default: html },
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Define and import a module
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
runtime.define("/Counter.jsx", `
|
|
30
|
+
import { createSignal } from "solid-js";
|
|
31
|
+
|
|
32
|
+
export default function Counter() {
|
|
33
|
+
const [count, setCount] = createSignal(0);
|
|
34
|
+
return (
|
|
35
|
+
<button onClick={() => setCount(value => value + 1)}>
|
|
36
|
+
{count()}
|
|
37
|
+
</button>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
`);
|
|
41
|
+
|
|
42
|
+
const module = await runtime.import("/Counter.jsx");
|
|
43
|
+
module.default;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Relative imports between runtime modules work normally:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
runtime.define("/ui/Button.jsx", `
|
|
50
|
+
export function Button(props) {
|
|
51
|
+
return <button>{props.children}</button>;
|
|
52
|
+
}
|
|
53
|
+
`);
|
|
54
|
+
|
|
55
|
+
runtime.define("/App.jsx", `
|
|
56
|
+
import { Button } from "./ui/Button.jsx";
|
|
57
|
+
|
|
58
|
+
export default function App() {
|
|
59
|
+
return <Button>Hello</Button>;
|
|
60
|
+
}
|
|
61
|
+
`);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Browser HTML adapter
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { createHTMLRuntime } from "solid-tag-runtime/html";
|
|
68
|
+
|
|
69
|
+
const htmlRuntime = createHTMLRuntime(runtime, {
|
|
70
|
+
scope: "main",
|
|
71
|
+
root: document,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await htmlRuntime.register();
|
|
75
|
+
await htmlRuntime.observe({ registerExisting: false });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Declarative source:
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<script
|
|
82
|
+
type="solid-jsx"
|
|
83
|
+
data-solid-runtime="main"
|
|
84
|
+
module="/App.jsx"
|
|
85
|
+
>
|
|
86
|
+
export default function App() {
|
|
87
|
+
return <h1>Hello</h1>;
|
|
88
|
+
}
|
|
89
|
+
</script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
See [HTML runtime](./html-runtime.md), [declarative rendering](./rendering.md), and [`<solid-render>`](./solid-render.md) for browser-specific behavior.
|
|
93
|
+
|
|
94
|
+
## Browser import maps
|
|
95
|
+
|
|
96
|
+
When loading through an import map, map both the package root and HTML subpath to the same release:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"imports": {
|
|
101
|
+
"solid-tag-runtime": "https://esm.sh/solid-tag-runtime@0.0.13",
|
|
102
|
+
"solid-tag-runtime/html": "https://esm.sh/solid-tag-runtime@0.0.13/html"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|