@deepseek-ai/dsh-client-modules 0.1.1-rc.2 → 0.1.2-alpha.3
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.i18n.yaml +2 -2
- package/README.md +107 -7
- package/README.zh.md +110 -10
- package/lib/client.js +67 -15
- package/lib/index.js +470 -102
- package/lib/types/client/manifest.d.ts +36 -15
- package/lib/types/client/system.d.ts +5 -3
- package/lib/types/index.d.ts +66 -17
- package/package.json +6 -9
|
@@ -38,26 +38,38 @@ declare module '@deepseek-ai/cordis' {
|
|
|
38
38
|
/**
|
|
39
39
|
* One composed client entry pushed by the host (a graph row). Wire
|
|
40
40
|
* single source: the host node half (package root) produces this same shape.
|
|
41
|
-
* `immediately` marks stage-one prefetch
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* `require` is synchronous (see {@link WebBootGraph.entries}).
|
|
41
|
+
* `immediately` marks stage-one prefetch. `inject` names package rows whose
|
|
42
|
+
* factories must arrive before this row materializes, while Cordis separately
|
|
43
|
+
* uses the same package edges to compose entries. `external` carries exact
|
|
44
|
+
* non-inject module requests (see {@link WebBootGraph.entries}).
|
|
46
45
|
*/
|
|
47
46
|
export interface WebBootEntry {
|
|
48
47
|
/** Entry name == package name. */
|
|
49
48
|
id: string;
|
|
50
|
-
/**
|
|
49
|
+
/** Revisioned single-resource combo endpoint used by HMR. */
|
|
51
50
|
url: string;
|
|
52
|
-
/**
|
|
51
|
+
/** Opaque plugin-artifact revision used for HMR cache busting. */
|
|
53
52
|
rev: string;
|
|
54
|
-
/** Package-name dependency edges
|
|
53
|
+
/** Package-name dependency edges used for factory arrival and plugin composition. */
|
|
55
54
|
inject?: string[];
|
|
56
55
|
/** Stage-one prefetch mark: load the script for factory registration during module-face boot. */
|
|
57
56
|
immediately?: boolean;
|
|
58
57
|
/** Non-baseline module specifiers this row requests; omitted when it requests none. */
|
|
59
58
|
external?: string[];
|
|
60
59
|
}
|
|
60
|
+
/** Initial scheduling phase for one content-addressed combo script. */
|
|
61
|
+
export type WebBootBatchPhase = 'bootstrap' | 'application';
|
|
62
|
+
/** One initial combo script; a scheduling phase may span several descriptors. */
|
|
63
|
+
export interface WebBootBatch {
|
|
64
|
+
/** Parser-blocking bootstrap or preloaded application scheduling. */
|
|
65
|
+
phase: WebBootBatchPhase;
|
|
66
|
+
/** Content-addressed combo script endpoint. */
|
|
67
|
+
url: string;
|
|
68
|
+
/** Revision over the combined plugin script bytes and indexed source map. */
|
|
69
|
+
rev: string;
|
|
70
|
+
/** Graph entry ids whose factories the script registers, in execution order. */
|
|
71
|
+
entries: string[];
|
|
72
|
+
}
|
|
61
73
|
/** The composed client entry graph the host injects as `window.__DSH_BOOT__`. */
|
|
62
74
|
export interface WebBootGraph {
|
|
63
75
|
/** Consistency anchor over the whole graph (content + bundle hashes). */
|
|
@@ -68,15 +80,21 @@ export interface WebBootGraph {
|
|
|
68
80
|
* unrelated and remains owned by fiber service waiting.
|
|
69
81
|
*/
|
|
70
82
|
entries: WebBootEntry[];
|
|
83
|
+
/** Initial combo descriptors; every entry belongs to exactly one descriptor. */
|
|
84
|
+
batches: WebBootBatch[];
|
|
71
85
|
}
|
|
72
86
|
/** The npm-package view of one boot row: what the module table needs to fetch the bundle. */
|
|
73
87
|
export interface BootModuleRow {
|
|
74
88
|
/** Entry name == package name (module-table key). */
|
|
75
89
|
id: string;
|
|
76
|
-
/**
|
|
90
|
+
/** Revisioned single-resource combo endpoint used after HMR invalidation. */
|
|
77
91
|
url: string;
|
|
78
|
-
/**
|
|
92
|
+
/** Content-addressed combo endpoint used before the first HMR invalidation. */
|
|
93
|
+
initialUrl: string;
|
|
94
|
+
/** Opaque plugin-artifact revision used after HMR invalidation. */
|
|
79
95
|
rev: string;
|
|
96
|
+
/** Injected package rows whose factories arrive before this row materializes. */
|
|
97
|
+
inject: string[];
|
|
80
98
|
/** Module specifiers this row requests from the module table ([] when the wire omits them). */
|
|
81
99
|
external: string[];
|
|
82
100
|
}
|
|
@@ -171,7 +189,7 @@ export interface DshWindow {
|
|
|
171
189
|
/** HTML-installed facade: a pending registration queue, then the live module-system target. */
|
|
172
190
|
__ModuleLoader__?: ClientModuleLoaderTarget;
|
|
173
191
|
}
|
|
174
|
-
/** Per-module bookkeeping in {@link ClientModuleLoader.loadCache} (module-graph boundary
|
|
192
|
+
/** Per-module bookkeeping in {@link ClientModuleLoader.loadCache} (flat module-graph boundary). */
|
|
175
193
|
export interface ClientModuleRecord {
|
|
176
194
|
/** Module id (entry name / package name). */
|
|
177
195
|
id: string;
|
|
@@ -179,7 +197,7 @@ export interface ClientModuleRecord {
|
|
|
179
197
|
exports: unknown;
|
|
180
198
|
/** Owned `<style data-plugin>` tag ids (`data-plugin-css` values) injected during materialization. */
|
|
181
199
|
styles: string[];
|
|
182
|
-
/** Observed `require()` edges (module-graph boundary; only table words can appear
|
|
200
|
+
/** Observed `require()` edges (module-graph boundary; only table words can appear). */
|
|
183
201
|
edges: Set<string>;
|
|
184
202
|
}
|
|
185
203
|
/**
|
|
@@ -217,11 +235,14 @@ export interface ClientModuleLoader {
|
|
|
217
235
|
prefetch(id: string): Promise<void>;
|
|
218
236
|
/**
|
|
219
237
|
* Full reset of one non-bootstrap module: drop its registered factory and
|
|
220
|
-
* materialized record so the next prefetch/import
|
|
221
|
-
*
|
|
238
|
+
* materialized record so the next prefetch/import loads its one-resource
|
|
239
|
+
* combo script rather than the initial multi-resource request. The bootstrap
|
|
240
|
+
* module remains materialized.
|
|
222
241
|
* @param id - entry name to invalidate.
|
|
242
|
+
* @param rev - New content revision from the HMR frame; omitted to reuse
|
|
243
|
+
* the graph revision or for page-local modules that register directly.
|
|
223
244
|
*/
|
|
224
|
-
invalidate(id: string): void;
|
|
245
|
+
invalidate(id: string, rev?: string): void;
|
|
225
246
|
}
|
|
226
247
|
/** Internal construction inputs assembled by the modules bundle's bootstrap export. */
|
|
227
248
|
export interface ClientModuleSystemOptions {
|
|
@@ -13,8 +13,10 @@ export declare class ClientModuleSystem implements ClientModuleLoader {
|
|
|
13
13
|
private readonly seed;
|
|
14
14
|
private readonly factories;
|
|
15
15
|
private readonly bootstrapIds;
|
|
16
|
-
/** In-flight
|
|
16
|
+
/** In-flight script transport per URL; every row in one batch shares it. */
|
|
17
17
|
private readonly pendingArrival;
|
|
18
|
+
/** Single-resource combo URL selected by HMR after invalidating one row. */
|
|
19
|
+
private readonly reloadUrls;
|
|
18
20
|
/** Materialization re-entrancy guard: factory-form CJS cannot deliver partial exports, so a cycle is fatal. */
|
|
19
21
|
private readonly materializing;
|
|
20
22
|
private readonly graphRows;
|
|
@@ -28,7 +30,7 @@ export declare class ClientModuleSystem implements ClientModuleLoader {
|
|
|
28
30
|
private register;
|
|
29
31
|
/** Load one graph row so its factory is registered (idempotent per in-flight arrival). */
|
|
30
32
|
private arrive;
|
|
31
|
-
/** Register each unresolved dynamic request before
|
|
33
|
+
/** Register each injected package and unresolved dynamic request before its consumer. */
|
|
32
34
|
private arriveGraphRow;
|
|
33
35
|
/** Materialize a registered factory (synchronous; memoized in loadCache). */
|
|
34
36
|
private materialize;
|
|
@@ -41,6 +43,6 @@ export declare class ClientModuleSystem implements ClientModuleLoader {
|
|
|
41
43
|
private makeRequire;
|
|
42
44
|
import(specifier: string): Promise<unknown>;
|
|
43
45
|
prefetch(id: string): Promise<void>;
|
|
44
|
-
invalidate(id: string): void;
|
|
46
|
+
invalidate(id: string, rev?: string): void;
|
|
45
47
|
}
|
|
46
48
|
//# sourceMappingURL=system.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Node half of the client module system (`dsh.client` dual-face package): scans
|
|
3
3
|
* the host Loader's entries for packages declaring `dsh.client`, composes the
|
|
4
4
|
* `window.__DSH_BOOT__` entry graph (wire single source: {@link WebBootEntry}
|
|
5
|
-
* in `./client/manifest.ts`) in module-graph order, serves
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* injection table, and provides the
|
|
9
|
-
* half's registration/notification
|
|
5
|
+
* in `./client/manifest.ts`) in module-graph order, serves one-or-more-plugin
|
|
6
|
+
* combo scripts plus their source maps,
|
|
7
|
+
* contributes the registration facade, application preloads, bootstrap scripts,
|
|
8
|
+
* and graph to the webserver's index injection table, and provides the
|
|
9
|
+
* `clientModuleHost` service (the HMR node half's registration/notification
|
|
10
|
+
* face).
|
|
10
11
|
*
|
|
11
12
|
* Scanning is incremental per package — there is no full-rescan code path.
|
|
12
13
|
* Every cordis `internal/plugin` emission (fiber construction/disposal) marks
|
|
@@ -14,9 +15,10 @@
|
|
|
14
15
|
* against the live loader entries. The activation pass seeds the same dirty
|
|
15
16
|
* set with all current entries and flushes synchronously, so first scan and
|
|
16
17
|
* steady state share one implementation. Package metadata (including the
|
|
17
|
-
* negative "not a client package" verdict) is cached per
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* negative "not a client package" verdict) is cached per Loader specifier and
|
|
19
|
+
* owning-tree base URL until restart. The manifest package name identifies
|
|
20
|
+
* the browser module; distinct active Loader sources for that package are a
|
|
21
|
+
* composition error. Bundle content changes reach the graph only through
|
|
20
22
|
* {@link ClientModuleRegistry.rebuilt}.
|
|
21
23
|
* @module @deepseek-ai/dsh-client-modules
|
|
22
24
|
*/
|
|
@@ -25,13 +27,22 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
25
27
|
import type { IndexInjection } from '@deepseek-ai/dsh-host-webserver';
|
|
26
28
|
import type { WebBootEntry, WebBootGraph } from './client/manifest.ts';
|
|
27
29
|
export { stripClientSuffix } from './client/manifest.ts';
|
|
28
|
-
export type { BootManifest, BootModuleRow, BootPluginRow, WebBootEntry, WebBootGraph, } from './client/manifest.ts';
|
|
30
|
+
export type { BootManifest, BootModuleRow, BootPluginRow, WebBootBatch, WebBootBatchPhase, WebBootEntry, WebBootGraph, } from './client/manifest.ts';
|
|
29
31
|
declare module '@deepseek-ai/cordis' {
|
|
30
32
|
interface Context {
|
|
31
33
|
/** The web plugin table (provided by the client-modules node half). */
|
|
32
34
|
clientModules: ClientModuleRegistry;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
37
|
+
/** Filesystem baseline captured before a client artifact snapshot is read. */
|
|
38
|
+
export interface ClientArtifactBaseline {
|
|
39
|
+
/** Absolute path of the client bundle. */
|
|
40
|
+
readonly path: string;
|
|
41
|
+
/** Bundle modification time in milliseconds. */
|
|
42
|
+
readonly mtimeMs: number;
|
|
43
|
+
/** Bundle size in bytes. */
|
|
44
|
+
readonly size: number;
|
|
45
|
+
}
|
|
35
46
|
/**
|
|
36
47
|
* Order composed rows so every requested dynamic package precedes its
|
|
37
48
|
* consumers. An `external` specifier is either the package row it names
|
|
@@ -45,13 +56,14 @@ declare module '@deepseek-ai/cordis' {
|
|
|
45
56
|
export declare function orderByModuleGraph(entries: readonly WebBootEntry[]): WebBootEntry[];
|
|
46
57
|
/**
|
|
47
58
|
* The boot protocol as index injection rows. The inline registration queue
|
|
48
|
-
* precedes
|
|
49
|
-
* `
|
|
59
|
+
* precedes the application-batch preload and the blocking bootstrap batch. Its
|
|
60
|
+
* `create()` method materializes the modules
|
|
50
61
|
* bundle, delegates construction to that bundle, and leaves the same facade
|
|
51
62
|
* in live-registration mode. The graph global follows before the shell reads
|
|
52
63
|
* it.
|
|
53
64
|
* @param graph - the composed entry graph.
|
|
54
|
-
* @returns head rows in execution order: queue script,
|
|
65
|
+
* @returns head rows in execution order: queue script, application preloads,
|
|
66
|
+
* blocking bootstrap scripts, graph global.
|
|
55
67
|
*/
|
|
56
68
|
export declare function bootInjections(graph: WebBootGraph): IndexInjection[];
|
|
57
69
|
/**
|
|
@@ -64,11 +76,17 @@ export declare function bootInjections(graph: WebBootGraph): IndexInjection[];
|
|
|
64
76
|
export declare class ClientModuleRegistry extends Service {
|
|
65
77
|
static inject: string[];
|
|
66
78
|
private readonly table;
|
|
79
|
+
private readonly sources;
|
|
67
80
|
private readonly pkgMeta;
|
|
68
81
|
private readonly rebuildListeners;
|
|
69
82
|
private readonly graphListeners;
|
|
70
83
|
private readonly dirty;
|
|
71
|
-
private readonly
|
|
84
|
+
private readonly initialRevisionNonce;
|
|
85
|
+
private nextInitialRevision;
|
|
86
|
+
private responses;
|
|
87
|
+
private batchResponses;
|
|
88
|
+
/** One prior graph generation covers a request racing the HMR recomposition that replaced its URL. */
|
|
89
|
+
private previousBatchResponses;
|
|
72
90
|
private flushQueued;
|
|
73
91
|
private composed;
|
|
74
92
|
/**
|
|
@@ -87,6 +105,15 @@ export declare class ClientModuleRegistry extends Service {
|
|
|
87
105
|
* @returns the path, or undefined for an unknown id.
|
|
88
106
|
*/
|
|
89
107
|
clientPath(id: string): string | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Filesystem baseline captured before an entry's current bytes were read.
|
|
110
|
+
* HMR compares it with the live files when installing a watch, so a write
|
|
111
|
+
* between startup composition and watch installation cannot disappear into
|
|
112
|
+
* the watcher's initial state.
|
|
113
|
+
* @param id - entry id (package name).
|
|
114
|
+
* @returns the path and baseline, or undefined for an unknown id.
|
|
115
|
+
*/
|
|
116
|
+
artifactBaseline(id: string): ClientArtifactBaseline | undefined;
|
|
90
117
|
/**
|
|
91
118
|
* Re-hash one bundle (the HMR watch's registration hook — the only entry
|
|
92
119
|
* point through which bundle content changes reach the graph).
|
|
@@ -111,15 +138,37 @@ export declare class ClientModuleRegistry extends Service {
|
|
|
111
138
|
private notifyGraphChanged;
|
|
112
139
|
private resolveMeta;
|
|
113
140
|
/**
|
|
114
|
-
*
|
|
141
|
+
* Locate the manifest of the package the Loader mounts for a row. The row's
|
|
142
|
+
* module location is authoritative: the specifier resolves through the same
|
|
143
|
+
* Loader resolution that imported the row's host half — including any
|
|
144
|
+
* active ESM hooks — and the nearest ancestor manifest declaring the name
|
|
145
|
+
* owns the module. Tree-anchored `require` resolution remains only for
|
|
146
|
+
* runtimes without Node internals.
|
|
147
|
+
* @param loaderName - module specifier of the loader row.
|
|
148
|
+
* @param baseUrl - resolution base of the tree that owns the row.
|
|
149
|
+
* @returns the manifest path, or `undefined` when the name resolves to no package root.
|
|
150
|
+
*/
|
|
151
|
+
private locatePkgJson;
|
|
152
|
+
private nearestPackage;
|
|
153
|
+
private sourceKey;
|
|
154
|
+
/** Capture the bundle stats before reading its bytes. */
|
|
155
|
+
private captureArtifactBaseline;
|
|
156
|
+
/** Allocate an opaque initial row revision without inspecting artifact bytes. */
|
|
157
|
+
private allocateInitialRevision;
|
|
158
|
+
/**
|
|
159
|
+
* Read the activation-time bundle and optional source-map snapshots.
|
|
115
160
|
* @param pkgName - package that declares the client bundle.
|
|
116
161
|
* @param clientPath - absolute path of the built client artifact.
|
|
117
|
-
* @returns the
|
|
162
|
+
* @returns the immutable bytes plus the pre-read filesystem baseline.
|
|
118
163
|
* @throws {MissingClientBundleError} when the read fails with `ENOENT`; other filesystem errors are rethrown unchanged.
|
|
119
164
|
*/
|
|
120
|
-
private
|
|
121
|
-
/**
|
|
165
|
+
private initialBundleSnapshot;
|
|
166
|
+
/** Treat a missing, torn, or malformed development map as an identity-mapped artifact revision. */
|
|
167
|
+
private readSourceMapSnapshot;
|
|
168
|
+
/** Reconcile one entry name against the live Loader sources. @returns whether the table changed. */
|
|
122
169
|
private processOne;
|
|
170
|
+
private resolveSource;
|
|
171
|
+
private reconcilePackage;
|
|
123
172
|
private flush;
|
|
124
173
|
private readonly serveBundle;
|
|
125
174
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-modules",
|
|
3
3
|
"description": "Client module system, dual-face: node half composes the __DSH_BOOT__ entry graph (incremental dsh.client scan, bundle route, index tap, webPlugins service); browser half is the lazy-CJS module table the vendored cordis Loader consumes as its internal seam",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2-alpha.3",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
},
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@deepseek-ai/cordis-plugin-loader": "^1.0.
|
|
42
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.
|
|
43
|
-
"@deepseek-ai/dsh-invariants": "^0.1.
|
|
44
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
41
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
42
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.2-alpha.3",
|
|
43
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.3",
|
|
44
|
+
"@deepseek-ai/cordis": "^4.0.2"
|
|
45
45
|
},
|
|
46
46
|
"files": [
|
|
47
47
|
"lib/index.js",
|
|
@@ -50,10 +50,7 @@
|
|
|
50
50
|
"lib/types/**/*.d.ts"
|
|
51
51
|
],
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@deepseek-ai/
|
|
54
|
-
"@deepseek-ai/cordis": "^4.0.1",
|
|
55
|
-
"@deepseek-ai/cordis-plugin-loader": "^1.0.2",
|
|
56
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2"
|
|
53
|
+
"@deepseek-ai/cordis": "^4.0.2"
|
|
57
54
|
},
|
|
58
55
|
"scripts": {
|
|
59
56
|
"bundle": "tsdown",
|