@deepseek-ai/dsh-client-hmr 0.1.6-alpha.2 → 0.1.7-alpha.2
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 +2 -2
- package/README.zh.md +2 -2
- package/lib/client.js +6 -4
- package/lib/index.js +8 -5
- package/lib/types/client/index.d.ts +0 -1
- package/lib/types/events.d.ts +5 -0
- package/package.json +8 -8
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/hmr/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: a0c658ea059dbd9f5b7862225baa0831218c4c9f
|
|
6
|
+
README.zh.md: 7f6b7d17b764f7506ae7f203436a648667ac21ab
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ The shipped Web composition mounts this transport for live plugin changes. Durin
|
|
|
29
29
|
|
|
30
30
|
### Starting the reload chain
|
|
31
31
|
|
|
32
|
-
Run `pnpm run dev:web
|
|
32
|
+
Run `pnpm run dev:web`, which starts the host and the rebuild watchers together (`--no-serve` attaches only the watchers to a host started elsewhere, as does any watch process using the shared Client tsdown preset); rebuilt plugins are then swapped into the running browser automatically, one at a time. The preset stamps `lib/client.js` after all package-local chunks are written, so a chunk-only rebuild also advances the package revision without Host-side chunk scanning.
|
|
33
33
|
|
|
34
34
|
### What a reload does
|
|
35
35
|
|
|
@@ -59,7 +59,7 @@ This section explains how the reload chain is built; observable behavior is cove
|
|
|
59
59
|
|
|
60
60
|
### Design concept
|
|
61
61
|
|
|
62
|
-
The Host half watches each package's stamped entry artifact and serves `/plugins/events`. It forwards existing graph-change and rebuilt notifications; every new connection receives the current full graph. A graph describes the browser’s desired entries and carries no Host cleanup-completion guarantee. Host activation and cleanup remain owned by the Host lifecycle. The entry
|
|
62
|
+
The Host half watches each package's stamped entry artifact and serves `/plugins/events`. It forwards existing graph-change and rebuilt notifications; every new connection receives the current full graph. A graph describes the browser’s desired entries and carries no Host cleanup-completion guarantee. Host activation and cleanup remain owned by the Host lifecycle. The entry's mtime, ctime, and size identify the revision without hashing its contents; unchanged metadata requires no content read. Host restarts over unchanged artifacts keep the same revisions, so reconnecting the graph stream does not replace browser plugins. The browser half delegates both frame kinds to Client Modules, which serializes entry changes and waits for browser resource cleanup.
|
|
63
63
|
|
|
64
64
|
### The browser swap
|
|
65
65
|
|
package/README.zh.md
CHANGED
|
@@ -29,7 +29,7 @@ kind: "package-reference"
|
|
|
29
29
|
|
|
30
30
|
### 启动重载链路
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
运行 `pnpm run dev:web`,它会同时启动宿主与重建 watcher(`--no-serve` 则只把 watcher 接到别处启动的宿主上,使用共享 Client tsdown 预设的任何 watch 进程亦然);重建后的插件随后会被自动逐个替换进运行中的浏览器。该预设会在所有包内 chunk 写完后标记 `lib/client.js`,因此仅 chunk 发生重建也会推进包 revision,无需 Host 扫描 chunk。
|
|
33
33
|
|
|
34
34
|
### 一次重载做什么
|
|
35
35
|
|
|
@@ -59,7 +59,7 @@ kind: "package-reference"
|
|
|
59
59
|
|
|
60
60
|
### 设计理念
|
|
61
61
|
|
|
62
|
-
Host 半侧监听每个包带完成标记的入口产物,并提供 `/plugins/events`。它转发现有的图变化与重建通知;每个新连接都会收到当前完整图。图描述浏览器的目标条目,不保证 Host 清理已经完成。Host 的激活与清理仍由 Host
|
|
62
|
+
Host 半侧监听每个包带完成标记的入口产物,并提供 `/plugins/events`。它转发现有的图变化与重建通知;每个新连接都会收到当前完整图。图描述浏览器的目标条目,不保证 Host 清理已经完成。Host 的激活与清理仍由 Host 生命周期管理。入口的 mtime、ctime 和大小共同标识 revision,无需对其内容求哈希;元数据未变时无需读取内容。Host 重启时若产物未变,revision 保持不变,因此图流重连不会替换浏览器插件。浏览器半侧将两种帧都交给 Client Modules,由它串行处理条目变更并等待浏览器资源清理。
|
|
63
63
|
|
|
64
64
|
### 浏览器侧替换
|
|
65
65
|
|
package/lib/client.js
CHANGED
|
@@ -38,8 +38,11 @@ window.__ModuleLoader__.load({
|
|
|
38
38
|
default: return typeof record.type === "string" ? { kind: "unknown" } : { kind: "invalid" };
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
/**
|
|
42
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Document-relative form of {@link EVENTS_ENDPOINT} used by the browser half.
|
|
43
|
+
* See .agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.md.
|
|
44
|
+
*/
|
|
45
|
+
const EVENTS_ROUTE = "/plugins/events".slice(1);
|
|
43
46
|
//#endregion
|
|
44
47
|
//#region lib/types/client/index.js
|
|
45
48
|
/** Cordis plugin name. */
|
|
@@ -58,7 +61,7 @@ window.__ModuleLoader__.load({
|
|
|
58
61
|
});
|
|
59
62
|
};
|
|
60
63
|
ctx.effect(() => {
|
|
61
|
-
const source = new EventSource(
|
|
64
|
+
const source = new EventSource(EVENTS_ROUTE);
|
|
62
65
|
source.addEventListener("message", (event) => {
|
|
63
66
|
let value;
|
|
64
67
|
try {
|
|
@@ -77,7 +80,6 @@ window.__ModuleLoader__.load({
|
|
|
77
80
|
}, "client-hmr: event source");
|
|
78
81
|
}
|
|
79
82
|
//#endregion
|
|
80
|
-
exports.EVENTS_ENDPOINT = EVENTS_ENDPOINT;
|
|
81
83
|
exports.apply = apply;
|
|
82
84
|
exports.inject = inject;
|
|
83
85
|
exports.name = name;
|
package/lib/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import z from "@deepseek-ai/schemastery";
|
|
|
3
3
|
//#region lib/types/events.js
|
|
4
4
|
/** System SSE endpoint pushing graph/rebuilt frames (wire protocol constant). */
|
|
5
5
|
const EVENTS_ENDPOINT = "/plugins/events";
|
|
6
|
+
EVENTS_ENDPOINT.slice(1);
|
|
6
7
|
//#endregion
|
|
7
8
|
//#region lib/types/index.js
|
|
8
9
|
/**
|
|
@@ -28,12 +29,13 @@ function bundleStat(path) {
|
|
|
28
29
|
const bundle = statSync(path);
|
|
29
30
|
return {
|
|
30
31
|
mtimeMs: bundle.mtimeMs,
|
|
32
|
+
ctimeMs: bundle.ctimeMs,
|
|
31
33
|
size: bundle.size
|
|
32
34
|
};
|
|
33
35
|
}
|
|
34
|
-
/** Whether the executable bundle is unchanged since
|
|
36
|
+
/** Whether the executable bundle metadata is unchanged since its last publication. */
|
|
35
37
|
function sameBundleStat(left, right) {
|
|
36
|
-
return left.mtimeMs === right.mtimeMs && left.size === right.size;
|
|
38
|
+
return left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs && left.size === right.size;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Mount bundle watches and graph/rebuilt SSE delivery.
|
|
@@ -43,7 +45,7 @@ function sameBundleStat(left, right) {
|
|
|
43
45
|
function apply(ctx, config) {
|
|
44
46
|
const pollIntervalMs = config.pollIntervalMs;
|
|
45
47
|
const watched = /* @__PURE__ */ new Map();
|
|
46
|
-
const
|
|
48
|
+
const publish = (id, watch, current) => {
|
|
47
49
|
try {
|
|
48
50
|
ctx.clientModules.rebuilt(id);
|
|
49
51
|
} catch (error) {
|
|
@@ -54,6 +56,7 @@ function apply(ctx, config) {
|
|
|
54
56
|
ctx.logger.warn(error);
|
|
55
57
|
}
|
|
56
58
|
watch.mtimeMs = current.mtimeMs;
|
|
59
|
+
watch.ctimeMs = current.ctimeMs;
|
|
57
60
|
watch.size = current.size;
|
|
58
61
|
watch.dirty = false;
|
|
59
62
|
};
|
|
@@ -71,7 +74,7 @@ function apply(ctx, config) {
|
|
|
71
74
|
if (error.code !== "ENOENT") ctx.logger.warn(error);
|
|
72
75
|
return;
|
|
73
76
|
}
|
|
74
|
-
if (!sameBundleStat(current, watch))
|
|
77
|
+
if (!sameBundleStat(current, watch)) publish(id, watch, current);
|
|
75
78
|
};
|
|
76
79
|
const pollWatches = () => {
|
|
77
80
|
for (const [id, watch] of watched) {
|
|
@@ -84,7 +87,7 @@ function apply(ctx, config) {
|
|
|
84
87
|
continue;
|
|
85
88
|
}
|
|
86
89
|
if (!watch.dirty && sameBundleStat(current, watch)) continue;
|
|
87
|
-
|
|
90
|
+
publish(id, watch, current);
|
|
88
91
|
}
|
|
89
92
|
};
|
|
90
93
|
const syncWatches = () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Web SSE transport for page-owned client entry reconciliation and rebuilt code replacement. */
|
|
2
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
3
3
|
export type { PluginsEventFrame } from '../events.ts';
|
|
4
|
-
export { EVENTS_ENDPOINT } from '../events.ts';
|
|
5
4
|
/** Cordis plugin name. */
|
|
6
5
|
export declare const name = "client-hmr";
|
|
7
6
|
/** Required service: the client module system whose entry controller handles received frames. */
|
package/lib/types/events.d.ts
CHANGED
|
@@ -36,4 +36,9 @@ export type PluginsEventParseResult = {
|
|
|
36
36
|
export declare function parsePluginsEventFrame(value: unknown): PluginsEventParseResult;
|
|
37
37
|
/** System SSE endpoint pushing graph/rebuilt frames (wire protocol constant). */
|
|
38
38
|
export declare const EVENTS_ENDPOINT = "/plugins/events";
|
|
39
|
+
/**
|
|
40
|
+
* Document-relative form of {@link EVENTS_ENDPOINT} used by the browser half.
|
|
41
|
+
* See .agents/notes/implemented/architecture/2026-09-14-web-document-relative-app-routes.md.
|
|
42
|
+
*/
|
|
43
|
+
export declare const EVENTS_ROUTE: string;
|
|
39
44
|
//# sourceMappingURL=events.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-hmr",
|
|
3
3
|
"description": "Web client graph synchronization and rebuilt-bundle reload transport",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.7-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -40,17 +40,17 @@
|
|
|
40
40
|
},
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@deepseek-ai/schemastery": "
|
|
43
|
+
"@deepseek-ai/schemastery": "~3.18.4"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@deepseek-ai/cordis": "
|
|
46
|
+
"@deepseek-ai/cordis": "~4.0.4"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@deepseek-ai/cordis-plugin-loader": "
|
|
50
|
-
"@deepseek-ai/dsh-client-modules": "
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/cordis": "
|
|
49
|
+
"@deepseek-ai/cordis-plugin-loader": "~1.0.5",
|
|
50
|
+
"@deepseek-ai/dsh-client-modules": "0.1.7-alpha.2",
|
|
51
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.7-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-invariants": "0.1.7-alpha.2",
|
|
53
|
+
"@deepseek-ai/cordis": "~4.0.4"
|
|
54
54
|
},
|
|
55
55
|
"files": [
|
|
56
56
|
"lib/index.js",
|