solid-tag-runtime 0.0.12 → 0.0.14
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 +243 -39
- package/README.md +122 -885
- package/docs/README.md +26 -0
- package/docs/api/compile-cache.md +103 -0
- package/docs/api/html.md +89 -0
- package/docs/api/runtime.md +87 -0
- package/docs/api/solid.md +71 -0
- package/docs/compile-cache.md +271 -0
- package/docs/getting-started.md +112 -0
- package/docs/html-runtime.md +120 -0
- package/docs/lifecycle-events.md +77 -0
- package/docs/modules.md +93 -0
- package/docs/rendering.md +71 -0
- package/docs/solid-render.md +111 -0
- package/docs/solid-runtime-setup.md +181 -0
- package/docs/wrapperless-delegation.md +81 -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/examples/solid-runtime.js +24 -0
- package/index.d.ts +183 -27
- package/package.json +11 -3
- package/solid.d.ts +77 -0
- package/src/compile-cache.js +340 -0
- package/src/compiler.js +86 -38
- package/src/html/delegated-events.js +69 -0
- package/src/html/delegation-host.js +29 -0
- package/src/index.js +6 -0
- package/src/render.js +4 -0
- package/src/runtime.js +656 -74
- package/src/solid/import-map.js +29 -0
- package/src/solid/index.js +67 -0
- package/src/solid/integration.js +30 -0
- package/src/solid/packages.js +24 -0
- package/src/solid/providers/esm-sh.js +81 -0
- package/src/solid/providers/index.js +22 -0
- package/src/solid/providers/jsdelivr.js +45 -0
- package/src/solid/resolve.js +287 -0
package/docs/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
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`, and optional Solid setup/provider logic lives in `solid-tag-runtime/solid`.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
- [Getting started](./getting-started.md)
|
|
8
|
+
- [Solid runtime setup and provider resolution](./solid-runtime-setup.md)
|
|
9
|
+
- [Runtime modules and resolution](./modules.md)
|
|
10
|
+
- [HTML runtime and ownership](./html-runtime.md)
|
|
11
|
+
- [Declarative rendering](./rendering.md)
|
|
12
|
+
- [Wrapperless Solid 2 delegation](./wrapperless-delegation.md)
|
|
13
|
+
- [`<solid-render>`](./solid-render.md)
|
|
14
|
+
- [Lifecycle events](./lifecycle-events.md)
|
|
15
|
+
- [Persistent compile cache](./compile-cache.md)
|
|
16
|
+
|
|
17
|
+
## API reference
|
|
18
|
+
|
|
19
|
+
- [Core runtime API](./api/runtime.md)
|
|
20
|
+
- [Solid integration API](./api/solid.md)
|
|
21
|
+
- [HTML runtime API](./api/html.md)
|
|
22
|
+
- [Compile-cache API](./api/compile-cache.md)
|
|
23
|
+
|
|
24
|
+
## Engineering design
|
|
25
|
+
|
|
26
|
+
The root [`ARCHITECTURE.md`](../ARCHITECTURE.md) is the engineering handoff and decision log. It documents internal invariants, compiler/linker boundaries, ownership rules, provider-resolution boundaries, 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,89 @@
|
|
|
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).
|
|
84
|
+
|
|
85
|
+
## Wrapperless delegated events
|
|
86
|
+
|
|
87
|
+
For bare `<script render>` ranges, automatic Solid delegated-event setup is available when the underlying runtime was created with `createSolidRuntime()` from `solid-tag-runtime/solid`.
|
|
88
|
+
|
|
89
|
+
The HTML adapter asks the runtime's private Solid integration to establish document-level delegation lazily, then keeps the declaration in its existing independent `createRoot() + insert()` lifecycle. Selector renders and `<solid-render>` retain their existing container semantics.
|
|
@@ -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,71 @@
|
|
|
1
|
+
# Solid integration API
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import {
|
|
5
|
+
createSolidRuntime,
|
|
6
|
+
loadSolidModules,
|
|
7
|
+
inspectSolidResolution,
|
|
8
|
+
SOLID_RUNTIME_PACKAGES,
|
|
9
|
+
TESTED_SOLID_VERSION,
|
|
10
|
+
} from "solid-tag-runtime/solid";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## `loadSolidModules(options?)`
|
|
14
|
+
|
|
15
|
+
Returns the standard Solid family as host-module namespaces:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const modules = await loadSolidModules({
|
|
19
|
+
source: "auto",
|
|
20
|
+
fallbackProvider: "esm.sh",
|
|
21
|
+
version: "2.0.0-rc.13",
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
|
|
27
|
+
- `source`: `"auto" | "host" | "esm.sh" | "jsdelivr"`
|
|
28
|
+
- `fallbackProvider`: `"esm.sh" | "jsdelivr"`
|
|
29
|
+
- `version`: provider fallback version when no versioned anchor exists
|
|
30
|
+
- `modules`: already-resolved standard namespaces
|
|
31
|
+
- `specifiers`: explicit URL/specifier overrides
|
|
32
|
+
- `document`: optional document for read-only import-map inspection
|
|
33
|
+
|
|
34
|
+
`source: "auto"` refuses to mix a partially resolved opaque host Solid family with CDN-generated siblings when the existing runtime identity cannot be established safely.
|
|
35
|
+
|
|
36
|
+
## `createSolidRuntime(options?)`
|
|
37
|
+
|
|
38
|
+
Async convenience factory:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const runtime = await createSolidRuntime({
|
|
42
|
+
modules: {
|
|
43
|
+
"@app/state": state,
|
|
44
|
+
},
|
|
45
|
+
solid: {
|
|
46
|
+
source: "auto",
|
|
47
|
+
fallbackProvider: "esm.sh",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
All ordinary runtime options remain available. `modules` supplied by the caller override automatic Solid defaults.
|
|
53
|
+
|
|
54
|
+
The factory also installs the private lazy delegation capability used by wrapperless HTML rendering.
|
|
55
|
+
|
|
56
|
+
## `inspectSolidResolution(options?)`
|
|
57
|
+
|
|
58
|
+
Read-only helper for tooling/debugging:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const info = inspectSolidResolution();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Returns detected import-map mappings plus inferred provider/version information. It does not import modules and does not mutate the page.
|
|
65
|
+
|
|
66
|
+
## Constants
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
SOLID_RUNTIME_PACKAGES;
|
|
70
|
+
TESTED_SOLID_VERSION;
|
|
71
|
+
```
|
|
@@ -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.
|