@deepseek-ai/dsh-client-modules 0.1.6-alpha.1 → 0.1.7-alpha.1

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.
@@ -29,6 +29,7 @@
29
29
  * composes the wire.
30
30
  */
31
31
  import type { DshClientManifest } from '@deepseek-ai/dsh-package-manifest';
32
+ import type { ClientEntries } from './entries.ts';
32
33
  import type { ClientModuleSystem } from './system.ts';
33
34
  declare module '@deepseek-ai/cordis' {
34
35
  interface Context {
@@ -47,7 +48,10 @@ declare module '@deepseek-ai/cordis' {
47
48
  export interface WebBootEntry {
48
49
  /** Entry name == package name. */
49
50
  id: string;
50
- /** Revisioned single-resource combo endpoint used by HMR. */
51
+ /**
52
+ * Revisioned single-resource combo reference used by HMR. It is relative to
53
+ * the document, so the browser resolves it under whatever mount served the page.
54
+ */
51
55
  url: string;
52
56
  /** Opaque plugin-artifact revision used for HMR cache busting. */
53
57
  rev: string;
@@ -58,22 +62,22 @@ export interface WebBootEntry {
58
62
  /** Non-baseline module specifiers this row requests; omitted when it requests none. */
59
63
  external?: string[];
60
64
  }
61
- /** Initial scheduling phase for one content-addressed combo script. */
65
+ /** Initial scheduling phase for one revisioned combo script. */
62
66
  export type WebBootBatchPhase = 'bootstrap' | 'application';
63
67
  /** One initial combo script; a scheduling phase may span several descriptors. */
64
68
  export interface WebBootBatch {
65
69
  /** Parser-blocking bootstrap or preloaded application scheduling. */
66
70
  phase: WebBootBatchPhase;
67
- /** Content-addressed combo script endpoint. */
71
+ /** Content-addressed combo script reference, document-relative like {@link WebBootEntry.url}. */
68
72
  url: string;
69
- /** Revision over the combined plugin script bytes and indexed source map. */
73
+ /** Revision derived from the ordered entry revisions. */
70
74
  rev: string;
71
75
  /** Graph entry ids whose factories the script registers, in execution order. */
72
76
  entries: string[];
73
77
  }
74
78
  /** The composed client entry graph the host injects as `window.__DSH_BOOT__`. */
75
79
  export interface WebBootGraph {
76
- /** Consistency anchor over the whole graph (content + bundle hashes). */
80
+ /** Consistency anchor over the current entry and batch descriptors. */
77
81
  rev: string;
78
82
  /**
79
83
  * Composed entries in module-graph order — a dynamic package row precedes
@@ -88,9 +92,9 @@ export interface WebBootGraph {
88
92
  export interface BootModuleRow {
89
93
  /** Entry name == package name (module-table key). */
90
94
  id: string;
91
- /** Revisioned single-resource combo endpoint used after HMR invalidation. */
95
+ /** Revisioned single-resource combo reference used after HMR invalidation. */
92
96
  url: string;
93
- /** Content-addressed combo endpoint used before the first HMR invalidation. */
97
+ /** Content-addressed combo reference used before the first HMR invalidation. */
94
98
  initialUrl: string;
95
99
  /** Opaque plugin-artifact revision used after HMR invalidation. */
96
100
  rev: string;
@@ -162,16 +166,25 @@ export declare function stripClientSuffix(spec: string): string;
162
166
  * @returns the manifest with optional plugin-view fields normalized.
163
167
  */
164
168
  export declare function parseBootManifest(wire: unknown): BootManifest;
169
+ /** Module resolver passed into a registered Client bundle factory. */
170
+ export interface ClientBundleRequire {
171
+ /** Resolve a module-table dependency synchronously. */
172
+ (specifier: string): unknown;
173
+ /** Load and resolve a package-local dynamic chunk asynchronously. */
174
+ async(specifier: string): Promise<unknown>;
175
+ }
165
176
  /** One client bundle's factory registration submitted through `window.__ModuleLoader__.load`. */
166
177
  export interface ClientBundleRegistration {
167
178
  /** Plugin id (package name) — the registration key; must match the graph row being executed. */
168
179
  id: string;
180
+ /** Package-local chunk filename; absent for the package's `client.js` entry. */
181
+ chunk?: string;
169
182
  /**
170
- * Closure factory holding the whole bundle body: receives the synchronous
171
- * require bound to the module table and returns the bundle's exports. Runs
172
- * once, at materialization.
183
+ * Closure factory holding the whole bundle body: receives the module-table
184
+ * require whose `async` operation loads generated chunks, and returns the
185
+ * bundle's exports. The factory runs once, at materialization.
173
186
  */
174
- factory: (require: (spec: string) => unknown) => Record<string, unknown>;
187
+ factory: (require: ClientBundleRequire) => Record<string, unknown>;
175
188
  }
176
189
  /** Inputs passed by the web entry when it creates the client module system. */
177
190
  export interface ClientModuleCreateOptions {
@@ -226,9 +239,11 @@ export interface ClientModuleRecord {
226
239
  export interface ClientModuleLoader {
227
240
  /** Discriminant against Node's internal loader shapes ('v1'/'v2'). */
228
241
  version: 'client';
229
- /** Parsed Host boot graph shared with the web entry after module-system creation. */
242
+ /** Latest parsed Host graph, updated by live entry reconciliation. */
230
243
  manifest: BootManifest;
231
- /** Materialized-module registry: id record. The governance-side read API for entry exports. */
244
+ /** Page-owned entry reconciliation, shared by boot, graph updates and HMR. */
245
+ entries: ClientEntries;
246
+ /** Materialized-module registry: entry or package-local chunk id → record. */
232
247
  loadCache: Map<string, ClientModuleRecord>;
233
248
  /**
234
249
  * Internal contract consumed by the vendored Loader's `tree.import`. Resolves
@@ -252,8 +267,8 @@ export interface ClientModuleLoader {
252
267
  */
253
268
  prefetch(id: string): Promise<void>;
254
269
  /**
255
- * Full reset of one non-bootstrap module: drop its registered factory and
256
- * materialized record so the next prefetch/import loads its one-resource
270
+ * Full reset of one non-bootstrap package: drop its entry and chunk factories
271
+ * and materialized records so the next prefetch/import loads its one-resource
257
272
  * combo script rather than the initial multi-resource request. The bootstrap
258
273
  * module remains materialized.
259
274
  * @param id - entry name to invalidate.
@@ -264,7 +279,7 @@ export interface ClientModuleLoader {
264
279
  }
265
280
  /** Internal construction inputs assembled by the modules bundle's bootstrap export. */
266
281
  export interface ClientModuleSystemOptions {
267
- /** Parsed boot graph owned by the resulting module system. */
282
+ /** Boot graph validated by {@link parseBootManifest}, owned by the resulting module system. */
268
283
  manifest: BootManifest;
269
284
  /** Module-table seed: platform-singleton specifier → shell instance. */
270
285
  staticModules: Record<string, unknown>;
@@ -1,3 +1,4 @@
1
+ import { ClientEntries } from './entries.ts';
1
2
  import type { BootManifest, ClientModuleLoader, ClientModuleRecord, ClientModuleSystemOptions } from './manifest.ts';
2
3
  /**
3
4
  * The client module system: state tables plus the arrival/materialization
@@ -8,15 +9,18 @@ import type { BootManifest, ClientModuleLoader, ClientModuleRecord, ClientModule
8
9
  */
9
10
  export declare class ClientModuleSystem implements ClientModuleLoader {
10
11
  readonly version = "client";
11
- readonly manifest: BootManifest;
12
+ manifest: BootManifest;
13
+ readonly entries: ClientEntries;
12
14
  readonly loadCache: Map<string, ClientModuleRecord>;
13
15
  private readonly seed;
14
16
  private readonly factories;
15
17
  private readonly bootstrapIds;
16
18
  /** In-flight script transport per URL; every row in one batch shares it. */
17
19
  private readonly pendingArrival;
20
+ /** Owner generation captured by in-flight chunk requests and advanced on invalidation. */
21
+ private readonly generations;
18
22
  /** Single-resource combo URL selected by HMR after invalidating one row. */
19
- private readonly reloadUrls;
23
+ private readonly reloadTargets;
20
24
  /** Materialization re-entrancy guard: factory-form CJS cannot deliver partial exports, so a cycle is fatal. */
21
25
  private readonly materializing;
22
26
  private readonly graphRows;
@@ -34,15 +38,16 @@ export declare class ClientModuleSystem implements ClientModuleLoader {
34
38
  private arriveGraphRow;
35
39
  /** Materialize a registered factory (synchronous; memoized in loadCache). */
36
40
  private materialize;
37
- /**
38
- * The synchronous require answered to factories: seed → memoized record →
39
- * registered factory. Fetching is async and therefore unreachable
40
- * from here; an external dynamic package must have arrived before its
41
- * consumer materializes.
42
- */
41
+ /** Build the synchronous module-table require and its asynchronous chunk operation. */
43
42
  private makeRequire;
43
+ /** Load, register, and materialize one package-local dynamic chunk. */
44
+ private importChunk;
44
45
  import(specifier: string): Promise<unknown>;
45
46
  prefetch(id: string): Promise<void>;
47
+ /** Refresh descriptors and unowned factory revisions before any entry imports its dependencies. */
48
+ private updateManifest;
49
+ /** Retain live Loader modules and their transitive requests before evicting unreferenced graph records. */
50
+ private prune;
46
51
  invalidate(id: string, rev?: string): void;
47
52
  }
48
53
  //# sourceMappingURL=system.d.ts.map
@@ -40,6 +40,8 @@ export interface ClientArtifactBaseline {
40
40
  readonly path: string;
41
41
  /** Bundle modification time in milliseconds. */
42
42
  readonly mtimeMs: number;
43
+ /** Bundle status-change time in milliseconds, including writes that preserve mtime. */
44
+ readonly ctimeMs: number;
43
45
  /** Bundle size in bytes. */
44
46
  readonly size: number;
45
47
  }
@@ -81,8 +83,6 @@ export declare class ClientModuleRegistry extends Service {
81
83
  private readonly rebuildListeners;
82
84
  private readonly graphListeners;
83
85
  private readonly dirty;
84
- private readonly initialRevisionNonce;
85
- private nextInitialRevision;
86
86
  private responses;
87
87
  private batchResponses;
88
88
  /** One prior graph generation covers a request racing the HMR recomposition that replaced its URL. */
@@ -109,11 +109,12 @@ export declare class ClientModuleRegistry extends Service {
109
109
  /**
110
110
  * Serve an advertised revisioned bundle or source map without a Web server.
111
111
  * Unknown URLs return 404, unsupported methods return 405, and `HEAD`
112
- * returns the same immutable headers without a body.
112
+ * returns the same immutable headers without materializing a body. Each body
113
+ * is built once on its first `GET`; script construction never reads maps.
113
114
  * @param request - shell-carrier request for a `/plugins` resource.
114
115
  * @returns the exact response also exposed by the optional Web route.
115
116
  */
116
- fetchBundle(request: Request): Response;
117
+ fetchBundle(request: Request): Promise<Response>;
117
118
  /**
118
119
  * Filesystem baseline captured before an entry's current bytes were read.
119
120
  * HMR compares it with the live files when installing a watch, so a write
@@ -124,14 +125,15 @@ export declare class ClientModuleRegistry extends Service {
124
125
  */
125
126
  artifactBaseline(id: string): ClientArtifactBaseline | undefined;
126
127
  /**
127
- * Re-hash one bundle (the HMR watch's registration hook — the only entry
128
- * point through which bundle content changes reach the graph).
128
+ * Publish one completed bundle generation (the HMR watch's registration
129
+ * hook — the only entry point through which build changes reach the graph).
130
+ * Unchanged mtime, ctime and size preserve the graph without reading the bundle.
129
131
  * @param id - entry id (package name).
130
- * @returns the new rev, or undefined for an unknown id.
132
+ * @returns the current artifact rev, or undefined for an unknown id.
131
133
  */
132
134
  rebuilt(id: string): string | undefined;
133
135
  /**
134
- * Subscribe to bundle rebuilds; fires only when the re-hash changed the rev.
136
+ * Subscribe to bundle rebuilds; fires only when artifact metadata changes the rev.
135
137
  * @param listener - receives the entry id and its new bundle rev.
136
138
  * @returns the unsubscriber.
137
139
  */
@@ -162,23 +164,25 @@ export declare class ClientModuleRegistry extends Service {
162
164
  private sourceKey;
163
165
  /** Capture the bundle stats before reading its bytes. */
164
166
  private captureArtifactBaseline;
165
- /** Allocate an opaque initial row revision without inspecting artifact bytes. */
166
- private allocateInitialRevision;
167
167
  /**
168
- * Read the activation-time bundle and optional source-map snapshots.
168
+ * Read the activation-time bundle snapshot.
169
169
  * @param pkgName - package that declares the client bundle.
170
170
  * @param clientPath - absolute path of the built client artifact.
171
171
  * @returns the immutable bytes plus the pre-read filesystem baseline.
172
172
  * @throws {MissingClientBundleError} when the read fails with `ENOENT`; other filesystem errors are rethrown unchanged.
173
173
  */
174
174
  private initialBundleSnapshot;
175
- /** Treat a missing, torn, or malformed development map as an identity-mapped artifact revision. */
176
- private readSourceMapSnapshot;
175
+ /** Treat a missing, torn, or malformed development map as an identity section. */
176
+ private readonly readSourceMap;
177
177
  /** Reconcile one entry name against the live Loader sources. @returns whether the table changed. */
178
178
  private processOne;
179
179
  private resolveSource;
180
180
  private reconcilePackage;
181
181
  private flush;
182
+ /** Match an exact current-revision package-local chunk URL without reading its file. */
183
+ private chunkRequest;
184
+ /** Build a package-local chunk response only when its URL is requested. */
185
+ private chunkResponse;
182
186
  private bundleResource;
183
187
  private readonly serveBundle;
184
188
  }
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.6-alpha.1",
4
+ "version": "0.1.7-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -38,11 +38,12 @@
38
38
  },
39
39
  "license": "MIT",
40
40
  "devDependencies": {
41
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
42
- "@deepseek-ai/dsh-host-webserver": "^0.1.6-alpha.1",
43
- "@deepseek-ai/dsh-invariants": "^0.1.6-alpha.1",
44
- "@deepseek-ai/cordis": "^4.0.2",
45
- "@deepseek-ai/dsh-package-manifest": "^0.1.6-alpha.1"
41
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
42
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-alpha.1",
43
+ "@deepseek-ai/dsh-invariants": "^0.1.7-alpha.1",
44
+ "@deepseek-ai/cordis": "^4.0.3",
45
+ "@deepseek-ai/dsh-package-manifest": "^0.1.7-alpha.1",
46
+ "@deepseek-ai/dsh-client-store": "^0.1.7-alpha.1"
46
47
  },
47
48
  "files": [
48
49
  "lib/index.js",
@@ -51,7 +52,7 @@
51
52
  "lib/types/**/*.d.ts"
52
53
  ],
53
54
  "peerDependencies": {
54
- "@deepseek-ai/cordis": "^4.0.2"
55
+ "@deepseek-ai/cordis": "^4.0.3"
55
56
  },
56
57
  "scripts": {
57
58
  "bundle": "tsdown",