@deepseek-ai/dsh-client-test-runtime 0.0.1-rc.1 → 0.0.1-rc.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/lib/index.js +73 -3
- package/lib/types/index.d.ts +1 -0
- package/lib/types/remote.d.ts +49 -0
- package/lib/types/settings-scope.d.ts +2 -0
- package/package.json +13 -13
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Context, Inject } from "@deepseek-ai/cordis";
|
|
2
2
|
import { Fragment, createElement, useSyncExternalStore } from "react";
|
|
3
3
|
import { act, render, within } from "@testing-library/react";
|
|
4
|
-
import { ConversationEventRegistry, ConversationViewRegistry, EMPTY_CHAT_SNAPSHOT, SessionProvideChannel, SlotsService, createScope, createSnapshotStore, scopeOf } from "@deepseek-ai/dsh-client-runtime/client";
|
|
4
|
+
import { ConversationEventRegistry, ConversationViewRegistry, EMPTY_CHAT_SNAPSHOT, EMPTY_CONVERSATION_VIEWS, SessionProvideChannel, SlotsService, createScope, createSnapshotStore, scopeOf } from "@deepseek-ai/dsh-client-runtime/client";
|
|
5
5
|
import { createSlotRenderer } from "@deepseek-ai/dsh-client-web-react";
|
|
6
6
|
import { afterEach, beforeEach, expect, vi } from "vitest";
|
|
7
7
|
import { SESSION_SEARCH_RESULT_LIMIT } from "@deepseek-ai/dsh-host-apiproxy/api";
|
|
@@ -90,6 +90,7 @@ function registerDomSnapshotSerializer() {
|
|
|
90
90
|
function conversationSnapshot(sessionId) {
|
|
91
91
|
return {
|
|
92
92
|
sessionId,
|
|
93
|
+
views: EMPTY_CONVERSATION_VIEWS,
|
|
93
94
|
chat: EMPTY_CHAT_SNAPSHOT,
|
|
94
95
|
nodes: [],
|
|
95
96
|
turnTimings: /* @__PURE__ */ new Map(),
|
|
@@ -289,6 +290,7 @@ var TestSessions = class {
|
|
|
289
290
|
current: void 0,
|
|
290
291
|
phase: "ready",
|
|
291
292
|
subagentsByParent: {},
|
|
293
|
+
tasksBySession: {},
|
|
292
294
|
currentAddress: void 0
|
|
293
295
|
});
|
|
294
296
|
this.channel = new SessionProvideChannel({
|
|
@@ -876,12 +878,15 @@ function stubSettingsScope() {
|
|
|
876
878
|
let snapshot = {
|
|
877
879
|
status: "loading",
|
|
878
880
|
value: void 0,
|
|
881
|
+
base: void 0,
|
|
882
|
+
user: void 0,
|
|
879
883
|
revision: void 0,
|
|
880
884
|
writable: false,
|
|
881
885
|
mode: "host"
|
|
882
886
|
};
|
|
883
887
|
const listeners = /* @__PURE__ */ new Set();
|
|
884
888
|
const set = vi.fn(() => Promise.resolve());
|
|
889
|
+
const unset = vi.fn(() => Promise.resolve());
|
|
885
890
|
return {
|
|
886
891
|
scope: {
|
|
887
892
|
getSnapshot: () => snapshot,
|
|
@@ -891,9 +896,11 @@ function stubSettingsScope() {
|
|
|
891
896
|
listeners.delete(listener);
|
|
892
897
|
};
|
|
893
898
|
},
|
|
894
|
-
set
|
|
899
|
+
set,
|
|
900
|
+
unset
|
|
895
901
|
},
|
|
896
902
|
set,
|
|
903
|
+
unset,
|
|
897
904
|
listenerCount: () => listeners.size,
|
|
898
905
|
publish: (next) => {
|
|
899
906
|
snapshot = {
|
|
@@ -905,6 +912,69 @@ function stubSettingsScope() {
|
|
|
905
912
|
};
|
|
906
913
|
}
|
|
907
914
|
//#endregion
|
|
915
|
+
//#region lib/types/remote.js
|
|
916
|
+
/**
|
|
917
|
+
* Remote service test double for the forwarded-event path. Feature specs need
|
|
918
|
+
* `ctx.remote.$on` to exist (their plugins inject `remote`) and need forwarded
|
|
919
|
+
* host events to reach those subscribers, but not the generated namespaces or
|
|
920
|
+
* the wire — so this double implements subscription and dispatch only.
|
|
921
|
+
*
|
|
922
|
+
* Dispatch is driven the same way production drives it: `client/runtime` owns the
|
|
923
|
+
* host frame sink and hands each decoded `host/remote-event` frame to
|
|
924
|
+
* `$dispatch`. A spec therefore exercises its refresh chains by calling
|
|
925
|
+
* `$dispatch(name, args)` on this double.
|
|
926
|
+
*
|
|
927
|
+
* `$mount` rejects: a spec that reaches a generated namespace through this
|
|
928
|
+
* double has outgrown it and needs the real Client Remote service.
|
|
929
|
+
*
|
|
930
|
+
* One deliberate asymmetry with production: a throwing listener propagates out
|
|
931
|
+
* of the emit instead of being contained and logged, so a spec cannot lean on
|
|
932
|
+
* this double for the containment guarantee `$on` documents — assert that
|
|
933
|
+
* against the real service.
|
|
934
|
+
*/
|
|
935
|
+
var TestRemote = class {
|
|
936
|
+
subscriptions = /* @__PURE__ */ new Map();
|
|
937
|
+
/**
|
|
938
|
+
* Register the double as `ctx.remote`.
|
|
939
|
+
* @param ctx - the spec's root Context.
|
|
940
|
+
*/
|
|
941
|
+
constructor(ctx) {
|
|
942
|
+
ctx.provide("remote", this);
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Deliver one forwarded host event to its subscribers, standing in for the
|
|
946
|
+
* carrier that owns the frame sink.
|
|
947
|
+
* @param event - forwarded host event name.
|
|
948
|
+
* @param args - the Host argument list, verbatim.
|
|
949
|
+
*/
|
|
950
|
+
$dispatch(event, args) {
|
|
951
|
+
const listeners = this.subscriptions.get(event);
|
|
952
|
+
if (listeners === void 0) return;
|
|
953
|
+
for (const listener of [...listeners]) listener(...args);
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Subscribe to one forwarded host event.
|
|
957
|
+
* @param event - forwarded host event name.
|
|
958
|
+
* @param listener - receives the Host argument list verbatim.
|
|
959
|
+
* @returns disposer removing this subscription.
|
|
960
|
+
*/
|
|
961
|
+
$on(event, listener) {
|
|
962
|
+
const listeners = this.subscriptions.get(event) ?? /* @__PURE__ */ new Set();
|
|
963
|
+
this.subscriptions.set(event, listeners);
|
|
964
|
+
listeners.add(listener);
|
|
965
|
+
return () => {
|
|
966
|
+
listeners.delete(listener);
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Generated-namespace mount, unsupported by this double.
|
|
971
|
+
* @returns never; always rejects.
|
|
972
|
+
*/
|
|
973
|
+
$mount() {
|
|
974
|
+
return Promise.reject(/* @__PURE__ */ new Error("TestRemote: $mount needs the real Client Remote service"));
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
//#endregion
|
|
908
978
|
//#region lib/types/translate.js
|
|
909
979
|
/**
|
|
910
980
|
* Test double of the locale lookup chain: a translate stub over plain
|
|
@@ -1256,4 +1326,4 @@ var SlotTestRuntime = class SlotTestRuntime {
|
|
|
1256
1326
|
}
|
|
1257
1327
|
};
|
|
1258
1328
|
//#endregion
|
|
1259
|
-
export { FixtureSession, SlotTestRuntime, TestRoot, TestSessions, TestWorkspaces, conversationSnapshot, domSnapshotSerializer, makeTranslate, registerDomSnapshotSerializer, stubSettingsScope, usePinnedBrowserLanguages, workspaceListState };
|
|
1329
|
+
export { FixtureSession, SlotTestRuntime, TestRemote, TestRoot, TestSessions, TestWorkspaces, conversationSnapshot, domSnapshotSerializer, makeTranslate, registerDomSnapshotSerializer, stubSettingsScope, usePinnedBrowserLanguages, workspaceListState };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export { FixtureSession, TestSessions } from './sessions.ts';
|
|
|
25
25
|
export { stubSettingsScope } from './settings-scope.ts';
|
|
26
26
|
export type { StubSettingsScope } from './settings-scope.ts';
|
|
27
27
|
export { TestWorkspaces } from './workspaces.ts';
|
|
28
|
+
export { TestRemote } from './remote.ts';
|
|
28
29
|
export { conversationSnapshot, workspaceListState } from './fixtures.ts';
|
|
29
30
|
export type { SessionBehaviorOverrides, SessionFixture, Stabilizer } from './fixtures.ts';
|
|
30
31
|
export { makeTranslate } from './translate.ts';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Test-owned Remote face: `$on` subscriptions driven by the internal forwarded-event plumbing. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
/**
|
|
4
|
+
* Remote service test double for the forwarded-event path. Feature specs need
|
|
5
|
+
* `ctx.remote.$on` to exist (their plugins inject `remote`) and need forwarded
|
|
6
|
+
* host events to reach those subscribers, but not the generated namespaces or
|
|
7
|
+
* the wire — so this double implements subscription and dispatch only.
|
|
8
|
+
*
|
|
9
|
+
* Dispatch is driven the same way production drives it: `client/runtime` owns the
|
|
10
|
+
* host frame sink and hands each decoded `host/remote-event` frame to
|
|
11
|
+
* `$dispatch`. A spec therefore exercises its refresh chains by calling
|
|
12
|
+
* `$dispatch(name, args)` on this double.
|
|
13
|
+
*
|
|
14
|
+
* `$mount` rejects: a spec that reaches a generated namespace through this
|
|
15
|
+
* double has outgrown it and needs the real Client Remote service.
|
|
16
|
+
*
|
|
17
|
+
* One deliberate asymmetry with production: a throwing listener propagates out
|
|
18
|
+
* of the emit instead of being contained and logged, so a spec cannot lean on
|
|
19
|
+
* this double for the containment guarantee `$on` documents — assert that
|
|
20
|
+
* against the real service.
|
|
21
|
+
*/
|
|
22
|
+
export declare class TestRemote {
|
|
23
|
+
private readonly subscriptions;
|
|
24
|
+
/**
|
|
25
|
+
* Register the double as `ctx.remote`.
|
|
26
|
+
* @param ctx - the spec's root Context.
|
|
27
|
+
*/
|
|
28
|
+
constructor(ctx: Context);
|
|
29
|
+
/**
|
|
30
|
+
* Deliver one forwarded host event to its subscribers, standing in for the
|
|
31
|
+
* carrier that owns the frame sink.
|
|
32
|
+
* @param event - forwarded host event name.
|
|
33
|
+
* @param args - the Host argument list, verbatim.
|
|
34
|
+
*/
|
|
35
|
+
$dispatch(event: string, args: readonly unknown[]): void;
|
|
36
|
+
/**
|
|
37
|
+
* Subscribe to one forwarded host event.
|
|
38
|
+
* @param event - forwarded host event name.
|
|
39
|
+
* @param listener - receives the Host argument list verbatim.
|
|
40
|
+
* @returns disposer removing this subscription.
|
|
41
|
+
*/
|
|
42
|
+
$on(event: string, listener: (...args: never[]) => void): () => void;
|
|
43
|
+
/**
|
|
44
|
+
* Generated-namespace mount, unsupported by this double.
|
|
45
|
+
* @returns never; always rejects.
|
|
46
|
+
*/
|
|
47
|
+
$mount(): Promise<() => Promise<void>>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=remote.d.ts.map
|
|
@@ -7,6 +7,8 @@ export interface StubSettingsScope<T> {
|
|
|
7
7
|
scope: SettingsScope<T>;
|
|
8
8
|
/** Spy behind `scope.set`; resolves immediately. */
|
|
9
9
|
set: ReturnType<typeof vi.fn>;
|
|
10
|
+
/** Spy behind `scope.unset`; resolves immediately. */
|
|
11
|
+
unset: ReturnType<typeof vi.fn>;
|
|
10
12
|
/** @returns how many listeners are currently subscribed (disposal assertions). */
|
|
11
13
|
listenerCount(): number;
|
|
12
14
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-test-runtime",
|
|
3
3
|
"description": "jsdom slot test runtime: real Cordis Context + SlotsService + web-react renderer with test-owned session/workspace doubles for feature specs",
|
|
4
|
-
"version": "0.0.1-rc.
|
|
4
|
+
"version": "0.0.1-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "restricted"
|
|
7
7
|
},
|
|
@@ -34,24 +34,24 @@
|
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": "^18.2.0",
|
|
36
36
|
"react-dom": "^18.2.0",
|
|
37
|
-
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.
|
|
38
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.
|
|
39
|
-
"@deepseek-ai/dsh-
|
|
40
|
-
"@deepseek-ai/dsh-
|
|
41
|
-
"@deepseek-ai/
|
|
42
|
-
"@deepseek-ai/
|
|
37
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.2",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.2",
|
|
39
|
+
"@deepseek-ai/dsh-host-apiproxy": "^0.0.1-rc.2",
|
|
40
|
+
"@deepseek-ai/dsh-client-web-react": "^0.0.1-rc.2",
|
|
41
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.2",
|
|
42
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/react": "~18.3.1",
|
|
46
46
|
"@types/react-dom": "~18.3.0",
|
|
47
47
|
"react": "^18.2.0",
|
|
48
48
|
"react-dom": "^18.2.0",
|
|
49
|
-
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.
|
|
50
|
-
"@deepseek-ai/dsh-client-
|
|
51
|
-
"@deepseek-ai/dsh-host-apiproxy": "^0.0.1-rc.
|
|
52
|
-
"@deepseek-ai/dsh-client-
|
|
53
|
-
"@deepseek-ai/
|
|
54
|
-
"@deepseek-ai/
|
|
49
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.2",
|
|
50
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.2",
|
|
51
|
+
"@deepseek-ai/dsh-host-apiproxy": "^0.0.1-rc.2",
|
|
52
|
+
"@deepseek-ai/dsh-client-web-react": "^0.0.1-rc.2",
|
|
53
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.2",
|
|
54
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
55
55
|
},
|
|
56
56
|
"files": [
|
|
57
57
|
"lib/index.js",
|