dsh-plugin-xujie-memory 0.5.0 → 0.7.0
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/ACCEPTANCE.md +37 -0
- package/BUILD-PROVENANCE.json +53 -0
- package/CHANGELOG.md +40 -1
- package/LICENSE +21 -21
- package/README.md +67 -17
- package/README_EN.md +54 -8
- package/cordis.patch.yml +49 -49
- package/lib/client.js +17219 -0
- package/lib/controller.js +307 -0
- package/lib/index.js +200 -14
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +15104 -0
- package/lib/typert.remote-client.d.ts +40 -0
- package/lib/typert.remote-client.d.ts.map +1 -0
- package/lib/typert.remote-client.js +15093 -0
- package/lib/types.d.ts +13 -0
- package/lib/types.js +1 -0
- package/package.json +49 -5
- package/python/specs/characters/aloof.json +14 -14
- package/python/specs/characters/gentle.json +14 -14
- package/python/specs/characters/tsundere.json +14 -14
- package/python/specs/debt.v1.json +31 -31
- package/python/specs/nickname.v1.json +16 -16
- package/python/specs/preference.v1.json +16 -16
- package/python/xujie_memory/__init__.py +123 -123
- package/python/xujie_memory/admission.py +211 -211
- package/python/xujie_memory/audit.py +377 -377
- package/python/xujie_memory/benchmark.py +281 -281
- package/python/xujie_memory/character.py +199 -199
- package/python/xujie_memory/console.py +41 -41
- package/python/xujie_memory/consolidate.py +356 -356
- package/python/xujie_memory/due.py +121 -121
- package/python/xujie_memory/emotion.py +573 -573
- package/python/xujie_memory/engine.py +1333 -1312
- package/python/xujie_memory/errors.py +98 -98
- package/python/xujie_memory/importance.py +104 -104
- package/python/xujie_memory/judge.py +350 -350
- package/python/xujie_memory/management.py +203 -0
- package/python/xujie_memory/memory.py +71 -10
- package/python/xujie_memory/orchestrator.py +690 -666
- package/python/xujie_memory/phrasing.py +292 -292
- package/python/xujie_memory/privacy.py +105 -0
- package/python/xujie_memory/schema.sql +492 -480
- package/python/xujie_memory/server.py +76 -0
- package/python/xujie_memory/specs.py +170 -170
- package/python/xujie_memory/summary.py +238 -238
- package/scripts/build.mjs +19 -0
- package/scripts/prepack.mjs +9 -0
- package/scripts/test-all.mjs +9 -0
- package/scripts/test-node.mjs +10 -0
- package/src/client/MemoryPanel.tsx +536 -0
- package/src/client/NeuralField.tsx +88 -0
- package/src/client/css.d.ts +4 -0
- package/src/client/icons.tsx +28 -0
- package/src/client/index.tsx +59 -0
- package/src/client/memory-adapter.ts +67 -0
- package/src/client/model.ts +79 -0
- package/src/client/neural/engine.ts +999 -0
- package/src/client/neural/morphology.ts +219 -0
- package/src/client/panel.css +337 -0
- package/src/client/types.ts +6 -0
- package/src/controller.ts +88 -0
- package/src/generated/typert.host.js +449 -0
- package/src/generated/typert.remote-client.js +438 -0
- package/src/index.ts +2 -0
- package/src/types.ts +13 -0
- package/test/cordis-fixture.mjs +5 -0
- package/test/management_regression.py +187 -0
- package/test/node-regression.entry.mjs +52 -0
- package/vendor/DSH-LICENSE.txt +21 -0
- package/vendor/THIRD-PARTY.md +6 -0
- package/vendor/dsh-protocol/index.ts +484 -0
- package/vendor/dsh-protocol/json-value.ts +53 -0
- package/vendor/dsh-protocol/owned-value.ts +39 -0
- package/vendor/dsh-protocol/principal.ts +17 -0
- package/vendor/dsh-protocol/remote-access.ts +38 -0
- package/vendor/dsh-protocol/remote-error.ts +49 -0
- package/vendor/dsh-protocol/remote-info.ts +161 -0
- package/vendor/dsh-protocol/types.ts +939 -0
- package/vendor/licenses/jridgewell-gen-mapping-MIT.txt +19 -0
- package/vendor/licenses/jridgewell-resolve-uri-MIT.txt +19 -0
- package/vendor/licenses/jridgewell-sourcemap-codec-MIT.txt +19 -0
- package/vendor/licenses/jridgewell-trace-mapping-MIT.txt +19 -0
- package/vendor/licenses/zod-MIT.txt +21 -0
|
@@ -0,0 +1,939 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiler-independent Typert protocol shared by business packages, generated
|
|
3
|
+
* Remote artifacts, the Host Gateway, and Client API implementations.
|
|
4
|
+
* @module @deepseek-ai/dsh-typert-protocol/types
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Context, Events } from '@deepseek-ai/cordis'
|
|
8
|
+
import type { Branded } from '@deepseek-ai/dsh-brand'
|
|
9
|
+
import type { ZodType } from 'zod'
|
|
10
|
+
import type { TypertOwnedValue } from './owned-value.ts'
|
|
11
|
+
|
|
12
|
+
declare const LOOKUP_HOST: unique symbol
|
|
13
|
+
declare const LOOKUP_WIRE: unique symbol
|
|
14
|
+
declare const CONTEXT_WIRE: unique symbol
|
|
15
|
+
declare const RESOURCE_ID: unique symbol
|
|
16
|
+
|
|
17
|
+
/** Type-level association between a Host object and its wire identity. */
|
|
18
|
+
export interface TypertLookup<Host, Wire> {
|
|
19
|
+
readonly [LOOKUP_HOST]: Host
|
|
20
|
+
readonly [LOOKUP_WIRE]: Wire
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Extract the Host object associated with one lookup declaration. */
|
|
24
|
+
export type TypertLookupHost<Lookup> = Lookup extends TypertLookup<infer Host, infer _Wire> ? Host : never
|
|
25
|
+
|
|
26
|
+
/** Extract the wire identity associated with one lookup declaration. */
|
|
27
|
+
export type TypertLookupWire<Lookup> = Lookup extends TypertLookup<infer _Host, infer Wire> ? Wire : never
|
|
28
|
+
|
|
29
|
+
/** Type-level association between a scoped Context kind and its wire identity. */
|
|
30
|
+
export interface TypertContext<Wire> {
|
|
31
|
+
readonly [CONTEXT_WIRE]: Wire
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Extract the wire identity associated with one scoped Context declaration. */
|
|
35
|
+
export type TypertContextWire<ContextType> = ContextType extends TypertContext<infer Wire> ? Wire : never
|
|
36
|
+
|
|
37
|
+
/** Merge-extensible Host object lookup declarations. */
|
|
38
|
+
export interface TypertLookupMap {}
|
|
39
|
+
|
|
40
|
+
/** Merge-extensible scoped Context declarations. */
|
|
41
|
+
export interface TypertContextMap {}
|
|
42
|
+
|
|
43
|
+
/** Type-level association between a resource kind and its identity type. */
|
|
44
|
+
export interface TypertResource<Id> {
|
|
45
|
+
readonly [RESOURCE_ID]: Id
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Extract the identity type associated with one resource declaration. */
|
|
49
|
+
export type TypertResourceId<Resource> = Resource extends TypertResource<infer Id> ? Id : never
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Merge-extensible resource kinds whose identities a Remote call or forwarded
|
|
53
|
+
* event may carry. The package that owns an identity type declares its kind;
|
|
54
|
+
* the value is that kind's identity type, a string type such as a branded id.
|
|
55
|
+
* `global` names the built-in identity-less resource and is never a kind here.
|
|
56
|
+
*/
|
|
57
|
+
export interface TypertResourceMap {}
|
|
58
|
+
|
|
59
|
+
/** One declared resource kind. */
|
|
60
|
+
export type TypertResourceKind = Extract<keyof TypertResourceMap, string>
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Per-kind resource readers called with one argument tuple spread
|
|
64
|
+
* positionally: plain reads returning one identity, several, or `undefined`
|
|
65
|
+
* for none.
|
|
66
|
+
* @template Args - the argument tuple the readers receive as parameters.
|
|
67
|
+
*/
|
|
68
|
+
export type TypertResourceReaders<Args extends readonly unknown[]> = {
|
|
69
|
+
readonly [Kind in TypertResourceKind]?: (...args: Args) =>
|
|
70
|
+
| TypertResourceId<TypertResourceMap[Kind]>
|
|
71
|
+
| readonly TypertResourceId<TypertResourceMap[Kind]>[]
|
|
72
|
+
| undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Type-erased resource reader as runtime carriers store it; callers spread
|
|
77
|
+
* the argument tuple into it and validate its result. Declared through a
|
|
78
|
+
* method so a reader typed by its own parameters is assignable without a cast.
|
|
79
|
+
*/
|
|
80
|
+
export type TypertResourceReader = { read(...args: readonly unknown[]): unknown }['read']
|
|
81
|
+
|
|
82
|
+
type TypertLookupEntry = TypertLookupMap[keyof TypertLookupMap]
|
|
83
|
+
type TypertWireForHost<Value, Entry> = Entry extends unknown
|
|
84
|
+
? Value extends TypertLookupHost<Entry> ? TypertLookupWire<Entry> : never
|
|
85
|
+
: never
|
|
86
|
+
|
|
87
|
+
/** A method parameter as it arrives on the wire: a lookup's Host object becomes its wire identity. */
|
|
88
|
+
export type RemoteWireValue<Value> = Value extends TypertLookupHost<TypertLookupEntry>
|
|
89
|
+
? TypertWireForHost<Value, TypertLookupEntry>
|
|
90
|
+
: Value
|
|
91
|
+
|
|
92
|
+
/** A method's positional parameters as the wire carries them. */
|
|
93
|
+
export type RemoteWireArgs<Args extends unknown[]> = { [Index in keyof Args]: RemoteWireValue<Args[Index]> }
|
|
94
|
+
|
|
95
|
+
/** Merge-extensible direct Remote method signatures generated for consumers. */
|
|
96
|
+
export interface TypertRemoteMap {}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Merge-extensible Remote failure vocabulary: this package declares the
|
|
100
|
+
* universal carrier codes once; the Gateway merges its infrastructure codes
|
|
101
|
+
* and every owner merges its domain codes next to the throwing code.
|
|
102
|
+
*/
|
|
103
|
+
export interface RemoteErrorDetailsMap {
|
|
104
|
+
/** Owner-side business validation refused the request; `issues` carries codec output when one produced it. */
|
|
105
|
+
'gateway/bad-request': { readonly issues?: readonly object[] }
|
|
106
|
+
/** The call was cancelled by the carrier signal or the backend. */
|
|
107
|
+
'gateway/cancelled': {}
|
|
108
|
+
/** Carrier, dispatch, or unclassified Host failure. */
|
|
109
|
+
'gateway/internal': {}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Every declared Remote failure code. */
|
|
113
|
+
export type RemoteErrorCode = keyof RemoteErrorDetailsMap
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* One Remote call's failure: the code-discriminated union of RemoteError
|
|
117
|
+
* instances, so a `code` branch narrows `details` with no cast.
|
|
118
|
+
*/
|
|
119
|
+
export type RemoteFailure = {
|
|
120
|
+
[Code in RemoteErrorCode]: import('./remote-error.ts').RemoteError<Code>
|
|
121
|
+
}[RemoteErrorCode]
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* What every generated Remote method resolves to. The Remote face itself folds
|
|
125
|
+
* carrier failures into the error branch, so no consumer wraps a call to
|
|
126
|
+
* recover one; only assembly faults (arity, an unmounted method, a missing
|
|
127
|
+
* Context adapter) still reject.
|
|
128
|
+
* @template T - the Host method's business result.
|
|
129
|
+
*/
|
|
130
|
+
export type RemoteResult<T> =
|
|
131
|
+
| { readonly ok: true; readonly value: T }
|
|
132
|
+
| { readonly ok: false; readonly error: RemoteFailure }
|
|
133
|
+
|
|
134
|
+
declare const STREAM_UPLINK: unique symbol
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* One Remote stream as a Host method returns it: the items it yields to the
|
|
138
|
+
* Client, iterated as a plain `AsyncIterable<Out>`. `In` is the type of the
|
|
139
|
+
* items the Client may send back on the same logical stream, read through
|
|
140
|
+
* `RemoteInvocation.uplink()`; it is carried only as a type-level marker. The
|
|
141
|
+
* default `never` declares a method that reads none, and its descriptor
|
|
142
|
+
* carries no uplink codec. A generated Client stream method returns the same
|
|
143
|
+
* stream as a `RemoteStreamHandle<Out, In>`.
|
|
144
|
+
* @template Out - item type the Host method yields.
|
|
145
|
+
* @template In - item type the Client may send; `never` when the method reads none.
|
|
146
|
+
*/
|
|
147
|
+
export type RemoteStream<Out, In = never> = AsyncIterable<Out> & { readonly [STREAM_UPLINK]?: In }
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* One open Remote stream as the Client holds it: the downlink items as an
|
|
151
|
+
* `AsyncIterable`, plus the uplink and cancellation of the same logical
|
|
152
|
+
* stream. A generated Client stream method returns it, and calling that
|
|
153
|
+
* method opens the stream: a holder that neither iterates nor disposes the
|
|
154
|
+
* handle keeps the Host stream alive. A handle stands for one generation:
|
|
155
|
+
* when the carrier is lost, iteration fails with the carrier error and the
|
|
156
|
+
* handle is finished.
|
|
157
|
+
* @template Out - item type the Host method yields.
|
|
158
|
+
* @template In - item type the Client may send; `never` when the method reads none.
|
|
159
|
+
*/
|
|
160
|
+
export interface RemoteStreamHandle<Out, In> extends AsyncIterable<Out> {
|
|
161
|
+
/**
|
|
162
|
+
* Send one uplink item. Items sent before the stream has opened are queued
|
|
163
|
+
* and sent once the `open` frame is on the wire. A top-level `undefined`
|
|
164
|
+
* travels as an `item` frame without `value`.
|
|
165
|
+
* @param item - item the Host validates against the method's uplink codec.
|
|
166
|
+
* @throws {Error} when the item is not a lossless JSON value, when `end()`
|
|
167
|
+
* was called, or once the stream has terminated.
|
|
168
|
+
*/
|
|
169
|
+
send(item: In): void
|
|
170
|
+
/** Half-close the uplink: the Host's `uplink()` iteration ends. Idempotent; ignored after termination. */
|
|
171
|
+
end(): void
|
|
172
|
+
/**
|
|
173
|
+
* Cancel the logical stream: send `cancel` unless a terminal frame has
|
|
174
|
+
* arrived, and end the downlink iterator quietly. Breaking out of
|
|
175
|
+
* `for await` early does the same.
|
|
176
|
+
*/
|
|
177
|
+
dispose(): void
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Merge-extensible scoped Remote method signatures generated for consumers. */
|
|
181
|
+
export interface TypertRemoteScopeMap {}
|
|
182
|
+
|
|
183
|
+
type TypertEventParameters<Event extends keyof Events> =
|
|
184
|
+
Events[Event] extends (...args: infer Args) => unknown ? Args : never
|
|
185
|
+
|
|
186
|
+
type TypertEventResult<Event extends keyof Events> =
|
|
187
|
+
Events[Event] extends (...args: never[]) => infer Result ? Result : never
|
|
188
|
+
|
|
189
|
+
type TypertProjectedContextKey = Extract<keyof TypertLookupMap, keyof TypertContextMap>
|
|
190
|
+
|
|
191
|
+
type TypertProjectedContextSubject = {
|
|
192
|
+
[Key in TypertProjectedContextKey]: TypertLookupHost<TypertLookupMap[Key]>
|
|
193
|
+
}[TypertProjectedContextKey]
|
|
194
|
+
|
|
195
|
+
type TypertAgentScopedRequest<Request> = Request extends object
|
|
196
|
+
? 'agent' extends keyof Request
|
|
197
|
+
? Exclude<Request['agent'], undefined> extends TypertProjectedContextSubject ? Request : never
|
|
198
|
+
: never
|
|
199
|
+
: never
|
|
200
|
+
|
|
201
|
+
type TypertWaterfallEvent<Event extends keyof Events> =
|
|
202
|
+
unknown extends ThisParameterType<Events[Event]>
|
|
203
|
+
? never
|
|
204
|
+
: TypertEventParameters<Event> extends [infer Request, infer Next]
|
|
205
|
+
? Next extends () => TypertEventResult<Event>
|
|
206
|
+
? TypertEventResult<Event> extends Promise<unknown>
|
|
207
|
+
? TypertAgentScopedRequest<Request> extends never ? never : Event
|
|
208
|
+
: never
|
|
209
|
+
: never
|
|
210
|
+
: never
|
|
211
|
+
|
|
212
|
+
type TypertForwardingMode<Event extends keyof Events> =
|
|
213
|
+
unknown extends ThisParameterType<Events[Event]>
|
|
214
|
+
? TypertEventResult<Event> extends void ? 'emit' : never
|
|
215
|
+
: TypertWaterfallEvent<Event> extends never ? never : 'waterfall'
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Cordis event names the Remote Event carrier can preserve without a second
|
|
219
|
+
* signature declaration: unscoped `void` notifications and scoped async
|
|
220
|
+
* waterfalls whose final parameter is their same-result `next()` callback.
|
|
221
|
+
*/
|
|
222
|
+
export type TypertForwardableEvent = {
|
|
223
|
+
[Event in keyof Events]: TypertForwardingMode<Event> extends never ? never : Event
|
|
224
|
+
}[keyof Events]
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Event and dispatch mode accepted by the Remote Event source. An `emit` entry
|
|
228
|
+
* may declare readers of the resources its payload carries; an
|
|
229
|
+
* entry without `resources` touches the built-in `global` resource. A
|
|
230
|
+
* non-owner Peer receives an `emit` notification only after an access
|
|
231
|
+
* decision and never receives a `waterfall`.
|
|
232
|
+
*/
|
|
233
|
+
export type TypertForwardableEventEntry = {
|
|
234
|
+
[Event in keyof Events]: TypertForwardingMode<Event> extends infer Mode
|
|
235
|
+
? Mode extends 'emit'
|
|
236
|
+
? {
|
|
237
|
+
readonly event: Event
|
|
238
|
+
readonly mode: Mode
|
|
239
|
+
readonly resources?: TypertResourceReaders<TypertEventParameters<Event>>
|
|
240
|
+
}
|
|
241
|
+
: Mode extends 'waterfall'
|
|
242
|
+
? { readonly event: Event; readonly mode: Mode }
|
|
243
|
+
: never
|
|
244
|
+
: never
|
|
245
|
+
}[keyof Events]
|
|
246
|
+
|
|
247
|
+
/** Merge-extensible forwarding selection declared once by the Host assembly. */
|
|
248
|
+
export interface TypertRemoteEventSelection {}
|
|
249
|
+
|
|
250
|
+
/** Legal `$on` keys selected from the carrier-compatible Cordis event declarations. */
|
|
251
|
+
export type TypertRemoteEvent = Extract<TypertForwardableEvent, keyof TypertRemoteEventSelection>
|
|
252
|
+
|
|
253
|
+
type TypertClientAgent<Value> =
|
|
254
|
+
Exclude<Value, undefined> extends TypertProjectedContextSubject
|
|
255
|
+
? Context | Extract<Value, undefined>
|
|
256
|
+
: Value
|
|
257
|
+
|
|
258
|
+
type TypertClientEventRequest<Request> = Request extends object
|
|
259
|
+
? { [Key in keyof Request]: Key extends 'agent' ? TypertClientAgent<Request[Key]> : Request[Key] }
|
|
260
|
+
: never
|
|
261
|
+
|
|
262
|
+
type TypertScopedClientEventListener<Event extends TypertRemoteEvent> =
|
|
263
|
+
Events[Event] extends (request: infer Request, next: infer Next) => infer Result
|
|
264
|
+
? (
|
|
265
|
+
this: Context,
|
|
266
|
+
request: TypertClientEventRequest<Request>,
|
|
267
|
+
next: Next,
|
|
268
|
+
) => Result
|
|
269
|
+
: never
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Listener derived from one selected Cordis event declaration. Scoped Host
|
|
273
|
+
* subjects become the resolved Client `Context`; one-way notifications retain
|
|
274
|
+
* their declaration unchanged.
|
|
275
|
+
* @template Event - selected Remote Event name.
|
|
276
|
+
*/
|
|
277
|
+
export type TypertClientEventListener<Event extends TypertRemoteEvent> =
|
|
278
|
+
unknown extends ThisParameterType<Events[Event]>
|
|
279
|
+
? Events[Event]
|
|
280
|
+
: TypertScopedClientEventListener<Event>
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Resolve one direct Remote namespace from the generated flat endpoint map.
|
|
284
|
+
* @template Namespace - wire namespace before the endpoint slash.
|
|
285
|
+
*/
|
|
286
|
+
export type TypertRemoteNamespace<Namespace extends string> = {
|
|
287
|
+
[Endpoint in keyof TypertRemoteMap as Endpoint extends `${Namespace}/${infer Method}`
|
|
288
|
+
? Method
|
|
289
|
+
: never]: TypertRemoteMap[Endpoint]
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Resolve one scoped Remote namespace across every generated Context kind.
|
|
294
|
+
* The calling Cordis Context supplies the concrete identity at runtime.
|
|
295
|
+
* @template Namespace - wire namespace between the Context prefix and method.
|
|
296
|
+
*/
|
|
297
|
+
export type TypertRemoteScopeNamespace<
|
|
298
|
+
Namespace extends string,
|
|
299
|
+
ContextKey extends string = string,
|
|
300
|
+
> = {
|
|
301
|
+
[Endpoint in keyof TypertRemoteScopeMap as Endpoint extends `${ContextKey}:${Namespace}/${infer Method}`
|
|
302
|
+
? Method
|
|
303
|
+
: never]: TypertRemoteScopeMap[Endpoint]
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
type TypertRemoteScopeNamespaceKey<
|
|
307
|
+
ContextKey extends string,
|
|
308
|
+
Endpoint = keyof TypertRemoteScopeMap,
|
|
309
|
+
> = Endpoint extends `${ContextKey}:${infer Namespace}/${string}` ? Namespace : never
|
|
310
|
+
|
|
311
|
+
/** Generated scoped Remote namespaces available to one Context kind. */
|
|
312
|
+
export type TypertRemoteScopeApi<ContextKey extends string> = {
|
|
313
|
+
[Namespace in TypertRemoteScopeNamespaceKey<ContextKey>]:
|
|
314
|
+
TypertRemoteScopeNamespace<Namespace, ContextKey>
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Merge-extensible direct namespace surface generated for Client Remote services. */
|
|
318
|
+
export interface TypertRemoteNamespaceMap {}
|
|
319
|
+
|
|
320
|
+
/** Awaitable disposer returned by Cordis-owned Typert registrations. */
|
|
321
|
+
export type TypertDisposer = () => Promise<void>
|
|
322
|
+
|
|
323
|
+
type StringKeyOf<Value> = Extract<keyof Value, string>
|
|
324
|
+
|
|
325
|
+
/** Minimal runtime-schema capability carried by strict generated codecs. */
|
|
326
|
+
export interface TypertSchema<Output = unknown> {
|
|
327
|
+
/**
|
|
328
|
+
* Parse and validate one boundary value.
|
|
329
|
+
* @param value - untrusted boundary value.
|
|
330
|
+
* @returns the validated value.
|
|
331
|
+
*/
|
|
332
|
+
parse(value: unknown): Output
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** Native byte views reconstructed by a Remote carrier have ordinary ArrayBuffer backing. */
|
|
336
|
+
export type RemoteDecoded<Value> = Value extends Uint8Array ? Uint8Array<ArrayBuffer>
|
|
337
|
+
: Value extends string | number | boolean | bigint | symbol ? Value
|
|
338
|
+
: Value extends object ? { [Key in keyof Value]: RemoteDecoded<Value[Key]> } : Value
|
|
339
|
+
|
|
340
|
+
/** Codec attached to one invocation parameter or result. */
|
|
341
|
+
export type TypertCodec<Value = unknown> =
|
|
342
|
+
| TypertRemoteValue<Value> & {
|
|
343
|
+
readonly mode: 'strict'
|
|
344
|
+
readonly typeSymbol: string
|
|
345
|
+
/**
|
|
346
|
+
* Decode a unary result whose fields require type-specific handling.
|
|
347
|
+
* @param value - result reconstructed by the RPC carrier.
|
|
348
|
+
* @returns the validated result, retaining native byte views.
|
|
349
|
+
*/
|
|
350
|
+
readonly decode?: ((value: unknown) => unknown) | undefined
|
|
351
|
+
/**
|
|
352
|
+
* Project typed binary fields into RPC result attachments.
|
|
353
|
+
* @param value - native unary result.
|
|
354
|
+
* @param writeBytes - records a byte view at its result-relative path and returns its JSON placeholder.
|
|
355
|
+
* @returns JSON metadata with untouched JSON subtrees retained.
|
|
356
|
+
*/
|
|
357
|
+
readonly encode?: ((value: unknown, writeBytes: (bytes: Uint8Array, path: readonly (string | number)[]) => null) => unknown) | undefined
|
|
358
|
+
}
|
|
359
|
+
| {
|
|
360
|
+
readonly mode: 'src-json'
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/** One ordered business parameter in a Remote invocation. */
|
|
364
|
+
export interface InvocationParameterDescriptor {
|
|
365
|
+
/** Source-level parameter name. */
|
|
366
|
+
readonly name: string
|
|
367
|
+
/** Source parameter documentation, independent of JSON Schema support. */
|
|
368
|
+
readonly description?: string
|
|
369
|
+
/** Required key in the wire `args` object. */
|
|
370
|
+
readonly wire: string
|
|
371
|
+
/** Whether the value is JSON or requires a registered Host lookup. */
|
|
372
|
+
readonly source: 'json' | 'lookup'
|
|
373
|
+
/** Lookup key when `source` is `lookup`. */
|
|
374
|
+
readonly lookup?: string
|
|
375
|
+
/** Boundary codec for the wire representation. */
|
|
376
|
+
readonly codec: TypertCodec
|
|
377
|
+
/** Missing wire fields decode to `undefined` only for an explicitly declared `T | undefined`. */
|
|
378
|
+
readonly acceptsUndefined?: true
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** Source position retained for diagnostics from generated definitions. */
|
|
382
|
+
export interface InvocationSourceLocation {
|
|
383
|
+
readonly file: string
|
|
384
|
+
readonly line: number
|
|
385
|
+
readonly column: number
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** Carrier-independent description of one exported method invocation. */
|
|
389
|
+
export interface InvocationDescriptor {
|
|
390
|
+
/** Globally stable generated identity. */
|
|
391
|
+
readonly id: string
|
|
392
|
+
/** Cordis service key owning the method. */
|
|
393
|
+
readonly service: string
|
|
394
|
+
/** Wire namespace, defaulting to the service key. */
|
|
395
|
+
readonly namespace: string
|
|
396
|
+
/** Public instance method name. */
|
|
397
|
+
readonly method: string
|
|
398
|
+
/** Service member invoked when the exported method name is an alias. */
|
|
399
|
+
readonly implementation?: string
|
|
400
|
+
/** Absent for unary calls; stream calls deliver every yielded item as the Host produced it. */
|
|
401
|
+
readonly mode?: 'stream'
|
|
402
|
+
/** Receiver selection mode. */
|
|
403
|
+
readonly invocation:
|
|
404
|
+
| { readonly kind: 'direct' }
|
|
405
|
+
| {
|
|
406
|
+
readonly kind: 'context'
|
|
407
|
+
readonly context: string
|
|
408
|
+
readonly wire: string
|
|
409
|
+
readonly codec: TypertCodec
|
|
410
|
+
}
|
|
411
|
+
/** Optional consuming-Context projection for one direct lookup parameter. */
|
|
412
|
+
readonly scope?: {
|
|
413
|
+
/** Context kind whose Client adapter supplies the identity. */
|
|
414
|
+
readonly context: string
|
|
415
|
+
/** Lookup parameter wire field replaced by the Context identity. */
|
|
416
|
+
readonly wire: string
|
|
417
|
+
}
|
|
418
|
+
/** Ordered business parameters. */
|
|
419
|
+
readonly parameters: readonly InvocationParameterDescriptor[]
|
|
420
|
+
/**
|
|
421
|
+
* Client-to-Host items of the same logical stream, generated from the `In`
|
|
422
|
+
* type argument of the method's `RemoteStream<Out, In>` return type; absent
|
|
423
|
+
* when `In` is `never`. The method reads the items through
|
|
424
|
+
* `RemoteInvocation.uplink()`, so nothing enters the parameter list.
|
|
425
|
+
*/
|
|
426
|
+
readonly uplink?: {
|
|
427
|
+
/** Codec validating every uplink item before `uplink()` delivers it. */
|
|
428
|
+
readonly codec: TypertCodec
|
|
429
|
+
}
|
|
430
|
+
/** Transport cancellation injected after business parameters instead of entering wire args. */
|
|
431
|
+
readonly cancellation?: {
|
|
432
|
+
/** Reserved final Host method parameter. */
|
|
433
|
+
readonly parameter: 'signal'
|
|
434
|
+
}
|
|
435
|
+
/** Codec for the unary result or each yielded stream item. */
|
|
436
|
+
readonly result: TypertCodec
|
|
437
|
+
/** Source-owned method documentation; ordinary methods need not have JSDoc. */
|
|
438
|
+
readonly description?: string
|
|
439
|
+
/** Source declaration used only for diagnostics. */
|
|
440
|
+
readonly sourceLocation?: InvocationSourceLocation
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Opaque identity of one Peer: a party admitted to this Host by the connection
|
|
445
|
+
* layer. "Peer" is a connection-layer word; the browser application keeps the
|
|
446
|
+
* word "Client".
|
|
447
|
+
*/
|
|
448
|
+
export type PeerId = Branded<'PeerId'>
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Merge-extensible caller identities. Each driver declares its own entry.
|
|
452
|
+
* Every entry is a JSON value with a unique literal `kind`, carries no
|
|
453
|
+
* credential, and is safe to persist in a Session log.
|
|
454
|
+
*/
|
|
455
|
+
export interface PrincipalMap {
|
|
456
|
+
/** The local user who owns this Host. */
|
|
457
|
+
owner: { readonly kind: 'owner' }
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/** One caller identity; the authorization layer reads only this. */
|
|
461
|
+
export type Principal = PrincipalMap[keyof PrincipalMap]
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* One Peer's session on this Host. Its creator owns it: `ctx` is the Cordis
|
|
465
|
+
* scope that owns connection-lifetime registrations and is disposed with the
|
|
466
|
+
* Peer, and `principal` is the caller identity fixed when the Peer was created.
|
|
467
|
+
*/
|
|
468
|
+
export interface PeerScope {
|
|
469
|
+
readonly id: PeerId
|
|
470
|
+
/** Connection-lifetime registrations; disposed with the Peer. */
|
|
471
|
+
readonly ctx: Context
|
|
472
|
+
/** Caller identity fixed at creation by in-process Host code; no wire field can set it. */
|
|
473
|
+
readonly principal: Principal
|
|
474
|
+
/** Aborted once the Peer is disposed; Remote streams that speak for the Peer end with it. */
|
|
475
|
+
readonly signal: AbortSignal
|
|
476
|
+
/** Whether the Peer may open a forwarded-event stream; this does not grant business permissions. */
|
|
477
|
+
readonly interactions: 'answer' | 'none'
|
|
478
|
+
/**
|
|
479
|
+
* Tear down every registration made through `ctx`.
|
|
480
|
+
* @returns settles once the scope has quiesced; racing calls share one completion.
|
|
481
|
+
*/
|
|
482
|
+
dispose(): Promise<void>
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/** Carrier capacity for buffered uplink frames of one logical stream. */
|
|
486
|
+
export interface RemoteUplinkWindow {
|
|
487
|
+
/** Maximum complete encoded frame bytes waiting for the Host consumer. */
|
|
488
|
+
readonly maxBytes: number
|
|
489
|
+
/** UTF-8 envelope bytes added to a compact JSON item with a present value field. */
|
|
490
|
+
readonly frameOverheadBytes: number
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* The context of one Remote call, reachable inside the receiving method as
|
|
495
|
+
* `this.ctx.invocation`. The Gateway derives the receiver from a Context that
|
|
496
|
+
* carries it, so no parameter is injected and nothing crosses the wire.
|
|
497
|
+
*/
|
|
498
|
+
export interface RemoteInvocation {
|
|
499
|
+
readonly request: {
|
|
500
|
+
readonly namespace: string
|
|
501
|
+
readonly method: string
|
|
502
|
+
readonly args: Readonly<Record<string, unknown>>
|
|
503
|
+
}
|
|
504
|
+
/** Cordis service key of the receiving Service. */
|
|
505
|
+
readonly service: string
|
|
506
|
+
/** Peer the call speaks for; every carrier names it explicitly. */
|
|
507
|
+
readonly peer: PeerScope
|
|
508
|
+
/** Carrier cancellation: Client cancel, socket close, or an uplink failure. */
|
|
509
|
+
readonly signal: AbortSignal
|
|
510
|
+
/** Carrier frame capacity; absent when the carrier imposes no encoded-frame inbox limit. */
|
|
511
|
+
readonly uplinkWindow?: RemoteUplinkWindow | undefined
|
|
512
|
+
/**
|
|
513
|
+
* The Client's uplink items for this call. Available once; a second call
|
|
514
|
+
* throws. With an uplink codec on the descriptor every item is decoded to
|
|
515
|
+
* `In`; without one items arrive as `unknown` after a JSON-safety check.
|
|
516
|
+
* Iteration ends when the Client ends its uplink; when the method finishes
|
|
517
|
+
* its downlink the Gateway calls the iterator's `return()` and unread items
|
|
518
|
+
* are dropped. `In` is the caller's assertion: the runtime decodes by the
|
|
519
|
+
* descriptor and does not cross-check it.
|
|
520
|
+
* @template In - item type the caller reads; the descriptor codec decides what arrives.
|
|
521
|
+
* @returns the single-consumer uplink iterable.
|
|
522
|
+
*/
|
|
523
|
+
uplink<In = unknown>(): AsyncIterable<In>
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** Generated Host contract selected explicitly by a Client assembly. */
|
|
527
|
+
export interface TypertRemoteContribution {
|
|
528
|
+
/** npm package that owns the Remote methods. */
|
|
529
|
+
readonly package: string
|
|
530
|
+
/** Consumer-side invocation descriptors generated from that package. */
|
|
531
|
+
readonly descriptors: readonly InvocationDescriptor[]
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/** Generated parser and optional lossless tool-schema projection of one Remote value. */
|
|
535
|
+
export interface TypertRemoteValue<Value = unknown> {
|
|
536
|
+
/** Materialize the generated parser without loading the owning Service. */
|
|
537
|
+
readonly create: () => TypertSchema<Value>
|
|
538
|
+
/** Source-owned value documentation, independent of tool projection support. */
|
|
539
|
+
readonly description?: string | undefined
|
|
540
|
+
/** Present when the value is representable in the tool-schema subset without losing constraints; may be derived lazily. */
|
|
541
|
+
readonly jsonSchema?: Readonly<Record<string, unknown>> | undefined
|
|
542
|
+
/** Projection failure for consumers that require JSON Schema; parsing remains available. */
|
|
543
|
+
readonly jsonSchemaError?: string | undefined
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/** Consumer-owned input validation; never changes Host dispatch or the business method declaration. */
|
|
547
|
+
export interface TypertRemoteInputOptions {
|
|
548
|
+
/** Reject undeclared fields in input objects; explicit dictionaries and JSON values remain open. */
|
|
549
|
+
readonly strict?: boolean
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/** A direct descriptor; DecodedOutput differs from its parser output only for carrier-reconstructed unary bytes. */
|
|
553
|
+
export type TypertRemoteMethod<Input extends object, Output, Mode extends 'unary' | 'stream' = 'unary', Uplink = never, DecodedOutput = Output> =
|
|
554
|
+
Omit<InvocationDescriptor, 'mode' | 'invocation' | 'result'>
|
|
555
|
+
& (Mode extends 'stream' ? { readonly mode: 'stream' } : { readonly mode?: never }) & {
|
|
556
|
+
/** Named invocation selects a direct Service method, not a Context receiver. */
|
|
557
|
+
readonly invocation: { readonly kind: 'direct' }
|
|
558
|
+
/**
|
|
559
|
+
* Select matching named-input parsing and tool-schema projection without changing dispatch.
|
|
560
|
+
* @param options - consumer-owned strictness; omission preserves ordinary Remote object handling.
|
|
561
|
+
* @returns the cached view for this policy; its parser and projection remain lazy.
|
|
562
|
+
*/
|
|
563
|
+
input(options?: TypertRemoteInputOptions): TypertRemoteValue<Input>
|
|
564
|
+
/** The descriptor's result or stream-item parser; parsing alone does not normalize native byte backing. */
|
|
565
|
+
readonly result: Extract<TypertCodec<Output>, { readonly mode: 'strict' }>
|
|
566
|
+
/**
|
|
567
|
+
* Invoke the mounted namespace method with named wire arguments.
|
|
568
|
+
* @param remote - caller-owned, unscoped Client Remote service; its mount owns availability.
|
|
569
|
+
* @param input - decoded named wire arguments.
|
|
570
|
+
* @param signal - caller-owned invocation lifetime.
|
|
571
|
+
* @returns the carrier-decoded unary result or complete stream handle, including uplink and disposal.
|
|
572
|
+
*/
|
|
573
|
+
invoke(remote: TypertClientRemote, input: Input, signal?: AbortSignal): Mode extends 'stream'
|
|
574
|
+
? RemoteStreamHandle<Output, Uplink>
|
|
575
|
+
: Promise<RemoteResult<DecodedOutput>>
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/** Ordinary contribution whose method index references its direct invocation descriptors. */
|
|
579
|
+
export interface TypertRemoteInfo<Methods extends Readonly<Record<string,
|
|
580
|
+
TypertRemoteMethod<object, unknown> | TypertRemoteMethod<object, unknown, 'stream', unknown>
|
|
581
|
+
>> = Readonly<Record<string, TypertRemoteMethod<object, unknown> | TypertRemoteMethod<object, unknown, 'stream', unknown>>>>
|
|
582
|
+
extends TypertRemoteContribution {
|
|
583
|
+
/** Exact generated keys and types; Context-only receivers are available only through descriptors. */
|
|
584
|
+
readonly methods: Methods
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/** Generated Zod factory and optional tool projection for one invocation value. */
|
|
588
|
+
export interface TypertRemoteCodecSpec extends Omit<Extract<TypertCodec, { readonly mode: 'strict' }>, 'create'> {
|
|
589
|
+
/** Materialize the generated Zod schema only when a parser is requested. */
|
|
590
|
+
readonly create: () => ZodType
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/** One ordered parameter; omitted wire names resolve to the source parameter name. */
|
|
594
|
+
export interface TypertRemoteParameterSpec extends Omit<InvocationParameterDescriptor, 'wire' | 'codec'> {
|
|
595
|
+
/** Explicit wire alias, notably for a Host lookup identity. */
|
|
596
|
+
readonly wire?: string
|
|
597
|
+
/** Ordinary Remote parser and projection for this parameter. */
|
|
598
|
+
readonly codec: TypertRemoteCodecSpec
|
|
599
|
+
/** Consumer-selected counterpart rejecting undeclared fields in explicit input objects. */
|
|
600
|
+
readonly strictCodec: TypertRemoteCodecSpec
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/** Static method facts; endpoint identity and named-call helpers are derived by the runtime factory. */
|
|
604
|
+
export interface TypertRemoteMethodSpec extends Omit<InvocationDescriptor, 'id' | 'namespace' | 'method' | 'parameters' | 'result'> {
|
|
605
|
+
/** Ordered Host parameters, including their wire representations. */
|
|
606
|
+
readonly parameters: readonly TypertRemoteParameterSpec[]
|
|
607
|
+
/** Successful unary result or stream item, with optional native-byte handling. */
|
|
608
|
+
readonly result: TypertRemoteCodecSpec
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/** Compiler-produced method definitions, independent of services, registration, and transport. */
|
|
612
|
+
export interface TypertRemoteSpec {
|
|
613
|
+
/** Package owning these methods. */
|
|
614
|
+
readonly package: string
|
|
615
|
+
/** Public endpoints; each method's invocation facts occur only once. */
|
|
616
|
+
readonly methods: Readonly<Record<`${string}/${string}`, TypertRemoteMethodSpec>>
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/** Client Remote capability implemented by the Gateway and consumed by Remote assemblies. */
|
|
620
|
+
export interface TypertClientRemote extends TypertRemoteNamespaceMap {
|
|
621
|
+
/**
|
|
622
|
+
* Mount one generated Host-for-Client contribution in the caller's fiber.
|
|
623
|
+
* @param contribution - explicitly selected Remote package artifact.
|
|
624
|
+
* @returns disposer after namespace services and concrete methods are ready.
|
|
625
|
+
*/
|
|
626
|
+
$mount(contribution: TypertRemoteContribution): Promise<TypertDisposer>
|
|
627
|
+
/**
|
|
628
|
+
* Subscribe to one forwarded Host event. Notifications run in registration
|
|
629
|
+
* order and isolate failures; scoped waterfalls return, delegate through
|
|
630
|
+
* `next()`, or reject the Host dispatch.
|
|
631
|
+
* @template Event - forwarded event name selected by the Host assembly.
|
|
632
|
+
* @param event - forwarded Host event name, unchanged on the wire.
|
|
633
|
+
* @param listener - receives the Client projection of the Cordis `Events` declaration.
|
|
634
|
+
* @returns disposer owned by the calling fiber.
|
|
635
|
+
*/
|
|
636
|
+
$on<Event extends TypertRemoteEvent>(event: Event, listener: TypertClientEventListener<Event>): () => void
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Resolve one validated wire identity, synchronously or asynchronously.
|
|
641
|
+
* @param id - validated wire identity.
|
|
642
|
+
* @returns the Host object, or `undefined` when unavailable.
|
|
643
|
+
*/
|
|
644
|
+
export type TypertLookupResolver<Host = unknown, Wire = unknown> = (
|
|
645
|
+
id: Wire,
|
|
646
|
+
) => Host | undefined | Promise<Host | undefined>
|
|
647
|
+
|
|
648
|
+
/** Resource kinds whose identity type is a wire identity; every kind for a type-erased provider. */
|
|
649
|
+
type TypertResourceKindFor<Wire> = unknown extends Wire
|
|
650
|
+
? TypertResourceKind
|
|
651
|
+
: { [Kind in TypertResourceKind]: [Wire] extends [TypertResourceId<TypertResourceMap[Kind]>] ? Kind : never }[TypertResourceKind]
|
|
652
|
+
|
|
653
|
+
/** Runtime provider for one declared Host object lookup. */
|
|
654
|
+
export interface TypertLookupProvider<Host = unknown, Wire = unknown> {
|
|
655
|
+
/** Source parameter name recognized by the SRC weak parser. */
|
|
656
|
+
readonly parameter: string
|
|
657
|
+
/** Wire field replacing the Host object parameter. */
|
|
658
|
+
readonly wire: string
|
|
659
|
+
/** Resource kind the wire identity names; a parameter of this lookup carries that resource. */
|
|
660
|
+
readonly resource?: TypertResourceKindFor<Wire>
|
|
661
|
+
/** Canonical Host type symbol used by strict generation. */
|
|
662
|
+
readonly hostTypeSymbol: string
|
|
663
|
+
/** Canonical wire type symbol used by strict generation. */
|
|
664
|
+
readonly wireTypeSymbol: string
|
|
665
|
+
/**
|
|
666
|
+
* Resolve a wire identity through the provider's default policy.
|
|
667
|
+
* @param id - validated wire identity.
|
|
668
|
+
* @returns the object, `undefined` when unavailable, or either asynchronously.
|
|
669
|
+
*/
|
|
670
|
+
resolve(id: Wire): Host | undefined | Promise<Host | undefined>
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/** Stable wire declaration retained after a lookup provider unloads. */
|
|
674
|
+
export interface TypertLookupDefinition {
|
|
675
|
+
/** Merge-declared lookup key. */
|
|
676
|
+
readonly key: string
|
|
677
|
+
/** Source parameter name recognized by the SRC weak parser. */
|
|
678
|
+
readonly parameter: string
|
|
679
|
+
/** Wire field replacing the Host object parameter. */
|
|
680
|
+
readonly wire: string
|
|
681
|
+
/** Canonical Host type symbol used by strict generation. */
|
|
682
|
+
readonly hostTypeSymbol: string
|
|
683
|
+
/** Canonical wire type symbol used by strict generation. */
|
|
684
|
+
readonly wireTypeSymbol: string
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/** Host wire-to-Context resolver plus the declaration used by strict Remote methods. */
|
|
688
|
+
export interface TypertHostContextAdapter<Wire = unknown> {
|
|
689
|
+
/** Wire field carrying the Context identity. */
|
|
690
|
+
readonly wire: string
|
|
691
|
+
/** Canonical wire type symbol used by strict generation. */
|
|
692
|
+
readonly wireTypeSymbol: string
|
|
693
|
+
/** Resource kind the wire identity names; a call scoped to this Context carries that resource. */
|
|
694
|
+
readonly resource?: TypertResourceKindFor<Wire>
|
|
695
|
+
/**
|
|
696
|
+
* Resolve a validated wire identity to a live Host Context.
|
|
697
|
+
* @param id - validated wire identity.
|
|
698
|
+
* @returns the Context, or `undefined` when it is unavailable.
|
|
699
|
+
*/
|
|
700
|
+
resolve(id: Wire): Context | undefined | Promise<Context | undefined>
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/** Composition-owned resolver replacing one Host Context adapter's default lookup policy. */
|
|
704
|
+
export type TypertHostContextResolver<Wire = unknown> = (
|
|
705
|
+
id: Wire,
|
|
706
|
+
) => Context | undefined | Promise<Context | undefined>
|
|
707
|
+
|
|
708
|
+
/** Client-side bidirectional Context adapter. */
|
|
709
|
+
export interface TypertClientContextAdapter<Wire = unknown> {
|
|
710
|
+
/**
|
|
711
|
+
* Read the identity represented by a live Client Context.
|
|
712
|
+
* @param ctx - Client Context inspected by a scoped Remote caller.
|
|
713
|
+
* @returns the wire identity, or `undefined` for another Context kind.
|
|
714
|
+
*/
|
|
715
|
+
identity(ctx: Context): Wire | undefined
|
|
716
|
+
/**
|
|
717
|
+
* Resolve a validated identity synchronously for one Client invocation.
|
|
718
|
+
* @param id - validated wire identity.
|
|
719
|
+
* @returns a borrowed or invocation-owned Client Context, or undefined when unavailable.
|
|
720
|
+
*/
|
|
721
|
+
resolve(id: Wire): Context | TypertOwnedValue<Context> | undefined
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/** Notification emitted after a Typert runtime registry changes. */
|
|
725
|
+
export interface TypertRegistryChange {
|
|
726
|
+
readonly kind: 'local' | 'remote' | 'lookup' | 'host-context' | 'client-context' | 'resource'
|
|
727
|
+
readonly key: string
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/** Listener for one Typert runtime registry. */
|
|
731
|
+
export type TypertRegistryListener = (change: TypertRegistryChange) => void
|
|
732
|
+
|
|
733
|
+
/** Current-environment invocation definitions. */
|
|
734
|
+
export interface TypertLocalRegistry {
|
|
735
|
+
/**
|
|
736
|
+
* Look up one invocation by `<namespace>/<method>`.
|
|
737
|
+
* @param endpoint - canonical endpoint.
|
|
738
|
+
* @returns the live descriptor, or `undefined` when absent.
|
|
739
|
+
*/
|
|
740
|
+
get(endpoint: string): InvocationDescriptor | undefined
|
|
741
|
+
/**
|
|
742
|
+
* Report whether a strict definition has existed during this Typert Service lifetime.
|
|
743
|
+
* @param endpoint - canonical endpoint.
|
|
744
|
+
* @returns `true` after the endpoint has been registered at least once, even if withdrawn.
|
|
745
|
+
*/
|
|
746
|
+
hasSeen(endpoint: string): boolean
|
|
747
|
+
/** @returns a registration-order snapshot of local descriptors. */
|
|
748
|
+
list(): readonly InvocationDescriptor[]
|
|
749
|
+
/**
|
|
750
|
+
* Observe later local-definition changes.
|
|
751
|
+
* @param listener - synchronous contained observer.
|
|
752
|
+
* @returns disposer for this subscription.
|
|
753
|
+
*/
|
|
754
|
+
subscribe(listener: TypertRegistryListener): TypertDisposer
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/** Consumer-selected Remote contribution registry. */
|
|
758
|
+
export interface TypertRemoteRegistry {
|
|
759
|
+
/**
|
|
760
|
+
* Register one generated contribution for the calling Cordis fiber.
|
|
761
|
+
* @param contribution - generated Remote descriptors.
|
|
762
|
+
* @returns disposer withdrawing the exact contribution.
|
|
763
|
+
*/
|
|
764
|
+
register(contribution: TypertRemoteContribution): TypertDisposer
|
|
765
|
+
/**
|
|
766
|
+
* Look up one Remote descriptor by endpoint.
|
|
767
|
+
* @param endpoint - canonical endpoint.
|
|
768
|
+
* @returns the descriptor, or `undefined` when unmounted.
|
|
769
|
+
*/
|
|
770
|
+
get(endpoint: string): InvocationDescriptor | undefined
|
|
771
|
+
/** @returns a registration-order snapshot of Remote descriptors. */
|
|
772
|
+
list(): readonly InvocationDescriptor[]
|
|
773
|
+
/**
|
|
774
|
+
* Observe later Remote contribution changes.
|
|
775
|
+
* @param listener - synchronous contained observer.
|
|
776
|
+
* @returns disposer for this subscription.
|
|
777
|
+
*/
|
|
778
|
+
subscribe(listener: TypertRegistryListener): TypertDisposer
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/** Runtime registry for Host object lookup providers. */
|
|
782
|
+
export interface TypertLookupRegistry {
|
|
783
|
+
/**
|
|
784
|
+
* Register one provider under its merge-declared key.
|
|
785
|
+
* @param key - lookup key.
|
|
786
|
+
* @param provider - owning package's live resolver.
|
|
787
|
+
* @returns disposer withdrawing the exact provider.
|
|
788
|
+
*/
|
|
789
|
+
register<K extends StringKeyOf<TypertLookupMap>>(
|
|
790
|
+
key: K,
|
|
791
|
+
provider: TypertLookupProvider<
|
|
792
|
+
TypertLookupHost<TypertLookupMap[K]>,
|
|
793
|
+
TypertLookupWire<TypertLookupMap[K]>
|
|
794
|
+
>,
|
|
795
|
+
): TypertDisposer
|
|
796
|
+
/**
|
|
797
|
+
* Replace one provider's default resolution policy while this contribution is active.
|
|
798
|
+
* Configuration may precede provider registration; without a live provider, `get()` remains unavailable.
|
|
799
|
+
* @param key - lookup key whose wire declaration remains provider-owned.
|
|
800
|
+
* @param resolver - composition-owned resolver used by every lookup of this key.
|
|
801
|
+
* @returns disposer restoring the provider's default resolver.
|
|
802
|
+
*/
|
|
803
|
+
configure<K extends StringKeyOf<TypertLookupMap>>(
|
|
804
|
+
key: K,
|
|
805
|
+
resolver: TypertLookupResolver<
|
|
806
|
+
TypertLookupHost<TypertLookupMap[K]>,
|
|
807
|
+
TypertLookupWire<TypertLookupMap[K]>
|
|
808
|
+
>,
|
|
809
|
+
): TypertDisposer
|
|
810
|
+
/**
|
|
811
|
+
* Look up one provider by runtime key.
|
|
812
|
+
* @param key - descriptor lookup key.
|
|
813
|
+
* @returns the live provider, or `undefined` when absent.
|
|
814
|
+
*/
|
|
815
|
+
get(key: string): TypertLookupProvider | undefined
|
|
816
|
+
/** @returns lookup declarations observed during this Typert Service lifetime. */
|
|
817
|
+
definitions(): readonly TypertLookupDefinition[]
|
|
818
|
+
/** @returns a snapshot of registered provider keys. */
|
|
819
|
+
keys(): readonly string[]
|
|
820
|
+
/**
|
|
821
|
+
* Observe later lookup changes.
|
|
822
|
+
* @param listener - synchronous contained observer.
|
|
823
|
+
* @returns disposer for this subscription.
|
|
824
|
+
*/
|
|
825
|
+
subscribe(listener: TypertRegistryListener): TypertDisposer
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/** Runtime registry for the Host and Client adapters of each Context kind. */
|
|
829
|
+
export interface TypertContextRegistry {
|
|
830
|
+
/**
|
|
831
|
+
* Register a Host Context adapter.
|
|
832
|
+
* @param key - merge-declared Context key.
|
|
833
|
+
* @param adapter - owning package's Host resolver and wire declaration.
|
|
834
|
+
* @returns disposer withdrawing the exact adapter.
|
|
835
|
+
*/
|
|
836
|
+
registerHost<K extends StringKeyOf<TypertContextMap>>(
|
|
837
|
+
key: K,
|
|
838
|
+
adapter: TypertHostContextAdapter<TypertContextWire<TypertContextMap[K]>>,
|
|
839
|
+
): TypertDisposer
|
|
840
|
+
/**
|
|
841
|
+
* Override one Host Context key's resolution policy for the calling fiber.
|
|
842
|
+
* Configuration may precede provider registration and restores the provider's default resolver on disposal.
|
|
843
|
+
* @param key - merge-declared Context key.
|
|
844
|
+
* @param resolver - composition-owned resolver used by every Host Context lookup of this key.
|
|
845
|
+
* @returns disposer restoring the provider's default resolver.
|
|
846
|
+
*/
|
|
847
|
+
configureHost<K extends StringKeyOf<TypertContextMap>>(
|
|
848
|
+
key: K,
|
|
849
|
+
resolver: TypertHostContextResolver<TypertContextWire<TypertContextMap[K]>>,
|
|
850
|
+
): TypertDisposer
|
|
851
|
+
/**
|
|
852
|
+
* Register a Client Context adapter.
|
|
853
|
+
* @param key - merge-declared Context key.
|
|
854
|
+
* @param adapter - owning package's bidirectional Client projection.
|
|
855
|
+
* @returns disposer withdrawing the exact adapter.
|
|
856
|
+
*/
|
|
857
|
+
registerClient<K extends StringKeyOf<TypertContextMap>>(
|
|
858
|
+
key: K,
|
|
859
|
+
adapter: TypertClientContextAdapter<TypertContextWire<TypertContextMap[K]>>,
|
|
860
|
+
): TypertDisposer
|
|
861
|
+
/**
|
|
862
|
+
* Look up a Host Context adapter; a configured resolver keeps the adapter's declaration and `resource`.
|
|
863
|
+
* @param key - descriptor Context key.
|
|
864
|
+
* @returns the adapter, or `undefined` when absent.
|
|
865
|
+
*/
|
|
866
|
+
getHost(key: string): TypertHostContextAdapter | undefined
|
|
867
|
+
/**
|
|
868
|
+
* Look up a Client Context adapter.
|
|
869
|
+
* @param key - descriptor Context key.
|
|
870
|
+
* @returns the adapter, or `undefined` when absent.
|
|
871
|
+
*/
|
|
872
|
+
getClient(key: string): TypertClientContextAdapter | undefined
|
|
873
|
+
/**
|
|
874
|
+
* Observe later Context adapter changes.
|
|
875
|
+
* @param listener - synchronous contained observer.
|
|
876
|
+
* @returns disposer for this subscription.
|
|
877
|
+
*/
|
|
878
|
+
subscribe(listener: TypertRegistryListener): TypertDisposer
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/** Default wire field of one resource kind. */
|
|
882
|
+
export interface TypertResourceDeclaration {
|
|
883
|
+
/** Top-level or first-object wire field holding one identity of the kind. */
|
|
884
|
+
readonly field: string
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/** One registered resource kind with its default wire field. */
|
|
888
|
+
export interface TypertResourceEntry extends TypertResourceDeclaration {
|
|
889
|
+
/** Registered resource kind. */
|
|
890
|
+
readonly kind: string
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/** Runtime registry of resource kinds' default wire fields. */
|
|
894
|
+
export interface TypertResourceRegistry {
|
|
895
|
+
/**
|
|
896
|
+
* Register one kind's default wire field for the calling fiber. Only the
|
|
897
|
+
* domain that owns the kind registers it.
|
|
898
|
+
* @param kind - merge-declared resource kind.
|
|
899
|
+
* @param declaration - the kind's default wire field.
|
|
900
|
+
* @returns disposer withdrawing the exact registration.
|
|
901
|
+
* @throws Error when the kind is already registered or is `global`, the built-in resource kind.
|
|
902
|
+
*/
|
|
903
|
+
register(kind: TypertResourceKind, declaration: TypertResourceDeclaration): TypertDisposer
|
|
904
|
+
/**
|
|
905
|
+
* Look up one kind's declaration.
|
|
906
|
+
* @param kind - resource kind.
|
|
907
|
+
* @returns the live declaration, or `undefined` when unregistered.
|
|
908
|
+
*/
|
|
909
|
+
get(kind: string): TypertResourceDeclaration | undefined
|
|
910
|
+
/** @returns a registration-order snapshot of registered kinds with their fields. */
|
|
911
|
+
entries(): readonly TypertResourceEntry[]
|
|
912
|
+
/**
|
|
913
|
+
* Observe later resource-kind changes.
|
|
914
|
+
* @param listener - synchronous contained observer.
|
|
915
|
+
* @returns disposer for this subscription.
|
|
916
|
+
*/
|
|
917
|
+
subscribe(listener: TypertRegistryListener): TypertDisposer
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
/** Minimal Typert runtime consumed through dependency inversion. */
|
|
921
|
+
export interface TypertRegistryContract {
|
|
922
|
+
readonly local: TypertLocalRegistry
|
|
923
|
+
readonly remotes: TypertRemoteRegistry
|
|
924
|
+
readonly lookups: TypertLookupRegistry
|
|
925
|
+
readonly contexts: TypertContextRegistry
|
|
926
|
+
readonly resources: TypertResourceRegistry
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
declare module '@deepseek-ai/cordis' {
|
|
930
|
+
interface Context {
|
|
931
|
+
typert: TypertRegistryContract
|
|
932
|
+
/**
|
|
933
|
+
* The Remote call this Context was derived for, or `undefined` on a
|
|
934
|
+
* Context no Remote call derived. A Service method reads it as
|
|
935
|
+
* `this.ctx.invocation`.
|
|
936
|
+
*/
|
|
937
|
+
readonly invocation: RemoteInvocation | undefined
|
|
938
|
+
}
|
|
939
|
+
}
|