@forthix/forthic 0.7.1 → 0.7.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/dist/cjs/forthic/interpreter.d.ts +2 -0
- package/dist/cjs/forthic/interpreter.js +10 -0
- package/dist/cjs/forthic/interpreter.js.map +1 -1
- package/dist/cjs/grpc/server.test.d.ts +1 -0
- package/dist/cjs/grpc/server.test.js +156 -0
- package/dist/cjs/grpc/server.test.js.map +1 -0
- package/dist/cjs/grpc/temporal_utils.d.ts +36 -0
- package/dist/cjs/grpc/temporal_utils.js +80 -0
- package/dist/cjs/grpc/temporal_utils.js.map +1 -0
- package/dist/cjs/websocket/action_cable_client.d.ts +106 -0
- package/dist/cjs/websocket/action_cable_client.js +269 -0
- package/dist/cjs/websocket/action_cable_client.js.map +1 -0
- package/dist/cjs/websocket/client.d.ts +103 -0
- package/dist/cjs/websocket/client.js +266 -0
- package/dist/cjs/websocket/client.js.map +1 -0
- package/dist/cjs/websocket/remote_module.d.ts +68 -0
- package/dist/cjs/websocket/remote_module.js +107 -0
- package/dist/cjs/websocket/remote_module.js.map +1 -0
- package/dist/cjs/websocket/remote_word.d.ts +53 -0
- package/dist/cjs/websocket/remote_word.js +93 -0
- package/dist/cjs/websocket/remote_word.js.map +1 -0
- package/dist/cjs/websocket/runtime_manager.d.ts +69 -0
- package/dist/cjs/websocket/runtime_manager.js +112 -0
- package/dist/cjs/websocket/runtime_manager.js.map +1 -0
- package/dist/esm/forthic/interpreter.d.ts +2 -0
- package/dist/esm/forthic/interpreter.js +11 -1
- package/dist/esm/forthic/interpreter.js.map +1 -1
- package/dist/esm/grpc/server.test.d.ts +1 -0
- package/dist/esm/grpc/server.test.js +121 -0
- package/dist/esm/grpc/server.test.js.map +1 -0
- package/dist/esm/grpc/temporal_utils.d.ts +36 -0
- package/dist/esm/grpc/temporal_utils.js +72 -0
- package/dist/esm/grpc/temporal_utils.js.map +1 -0
- package/dist/esm/websocket/action_cable_client.d.ts +106 -0
- package/dist/esm/websocket/action_cable_client.js +265 -0
- package/dist/esm/websocket/action_cable_client.js.map +1 -0
- package/dist/esm/websocket/client.d.ts +103 -0
- package/dist/esm/websocket/client.js +262 -0
- package/dist/esm/websocket/client.js.map +1 -0
- package/dist/esm/websocket/remote_module.d.ts +68 -0
- package/dist/esm/websocket/remote_module.js +103 -0
- package/dist/esm/websocket/remote_module.js.map +1 -0
- package/dist/esm/websocket/remote_word.d.ts +53 -0
- package/dist/esm/websocket/remote_word.js +89 -0
- package/dist/esm/websocket/remote_word.js.map +1 -0
- package/dist/esm/websocket/runtime_manager.d.ts +69 -0
- package/dist/esm/websocket/runtime_manager.js +108 -0
- package/dist/esm/websocket/runtime_manager.js.map +1 -0
- package/package.json +1 -1
- package/dist/cjs/forthic/decorators/schemaUtils.d.ts +0 -70
- package/dist/cjs/forthic/decorators/schemaUtils.js +0 -77
- package/dist/cjs/forthic/decorators/schemaUtils.js.map +0 -1
- package/dist/cjs/forthic/decorators/stackEffect.d.ts +0 -63
- package/dist/cjs/forthic/decorators/stackEffect.js +0 -179
- package/dist/cjs/forthic/decorators/stackEffect.js.map +0 -1
- package/dist/esm/forthic/decorators/schemaUtils.d.ts +0 -70
- package/dist/esm/forthic/decorators/schemaUtils.js +0 -72
- package/dist/esm/forthic/decorators/schemaUtils.js.map +0 -1
- package/dist/esm/forthic/decorators/stackEffect.d.ts +0 -63
- package/dist/esm/forthic/decorators/stackEffect.js +0 -174
- package/dist/esm/forthic/decorators/stackEffect.js.map +0 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocketRemoteModule - Module that wraps runtime-specific words from a remote runtime
|
|
3
|
+
* Mirrors RemoteModule from gRPC implementation
|
|
4
|
+
*/
|
|
5
|
+
import { Module } from '../forthic/module.js';
|
|
6
|
+
import { Interpreter } from '../forthic/interpreter.js';
|
|
7
|
+
import { ActionCableClient, type ModuleInfo } from './action_cable_client.js';
|
|
8
|
+
/**
|
|
9
|
+
* WebSocketRemoteModule - Module containing proxy words that execute in a remote runtime
|
|
10
|
+
*
|
|
11
|
+
* This module discovers words from a remote runtime (e.g., pandas module in Ruby)
|
|
12
|
+
* and creates WebSocketRemoteWord proxies for each discovered word. When used in TypeScript
|
|
13
|
+
* Forthic code, these words execute in the remote runtime via ActionCable.
|
|
14
|
+
*
|
|
15
|
+
* Example usage:
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const client = new ActionCableClient({ url: 'ws://localhost:3000/cable' });
|
|
18
|
+
* const pandasModule = new WebSocketRemoteModule('pandas', client, 'rails');
|
|
19
|
+
* await pandasModule.initialize();
|
|
20
|
+
* interp.register_module(pandasModule);
|
|
21
|
+
* interp.use_modules(['pandas']);
|
|
22
|
+
*
|
|
23
|
+
* // Now pandas words execute in Rails runtime
|
|
24
|
+
* await interp.run(`
|
|
25
|
+
* [ [[.name "Alice"] [.age 30]] REC]
|
|
26
|
+
* DF-FROM-RECORDS # Executes in Rails!
|
|
27
|
+
* `);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class WebSocketRemoteModule extends Module {
|
|
31
|
+
private client;
|
|
32
|
+
private runtimeName;
|
|
33
|
+
private initialized;
|
|
34
|
+
private moduleInfo;
|
|
35
|
+
/**
|
|
36
|
+
* @param moduleName - Name of the module in the remote runtime (e.g., "pandas")
|
|
37
|
+
* @param client - ActionCable client connected to the remote runtime
|
|
38
|
+
* @param runtimeName - Name of the runtime (e.g., "rails") for debugging
|
|
39
|
+
*/
|
|
40
|
+
constructor(moduleName: string, client: ActionCableClient, runtimeName?: string);
|
|
41
|
+
/**
|
|
42
|
+
* Initialize the module by discovering words from the remote runtime
|
|
43
|
+
*
|
|
44
|
+
* This must be called before the module is registered with an interpreter.
|
|
45
|
+
* It fetches the module metadata and creates WebSocketRemoteWord proxies for each word.
|
|
46
|
+
*/
|
|
47
|
+
initialize(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Override set_interp to ensure module is initialized
|
|
50
|
+
*/
|
|
51
|
+
set_interp(interp: Interpreter): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get the module metadata from the remote runtime
|
|
54
|
+
*/
|
|
55
|
+
getModuleInfo(): ModuleInfo | null;
|
|
56
|
+
/**
|
|
57
|
+
* Get runtime name for debugging
|
|
58
|
+
*/
|
|
59
|
+
getRuntimeName(): string;
|
|
60
|
+
/**
|
|
61
|
+
* Check if module is initialized
|
|
62
|
+
*/
|
|
63
|
+
isInitialized(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Get count of discovered words
|
|
66
|
+
*/
|
|
67
|
+
getWordCount(): number;
|
|
68
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocketRemoteModule - Module that wraps runtime-specific words from a remote runtime
|
|
3
|
+
* Mirrors RemoteModule from gRPC implementation
|
|
4
|
+
*/
|
|
5
|
+
import { Module } from '../forthic/module.js';
|
|
6
|
+
import { WebSocketRemoteWord } from './remote_word.js';
|
|
7
|
+
/**
|
|
8
|
+
* WebSocketRemoteModule - Module containing proxy words that execute in a remote runtime
|
|
9
|
+
*
|
|
10
|
+
* This module discovers words from a remote runtime (e.g., pandas module in Ruby)
|
|
11
|
+
* and creates WebSocketRemoteWord proxies for each discovered word. When used in TypeScript
|
|
12
|
+
* Forthic code, these words execute in the remote runtime via ActionCable.
|
|
13
|
+
*
|
|
14
|
+
* Example usage:
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const client = new ActionCableClient({ url: 'ws://localhost:3000/cable' });
|
|
17
|
+
* const pandasModule = new WebSocketRemoteModule('pandas', client, 'rails');
|
|
18
|
+
* await pandasModule.initialize();
|
|
19
|
+
* interp.register_module(pandasModule);
|
|
20
|
+
* interp.use_modules(['pandas']);
|
|
21
|
+
*
|
|
22
|
+
* // Now pandas words execute in Rails runtime
|
|
23
|
+
* await interp.run(`
|
|
24
|
+
* [ [[.name "Alice"] [.age 30]] REC]
|
|
25
|
+
* DF-FROM-RECORDS # Executes in Rails!
|
|
26
|
+
* `);
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class WebSocketRemoteModule extends Module {
|
|
30
|
+
client;
|
|
31
|
+
runtimeName;
|
|
32
|
+
initialized = false;
|
|
33
|
+
moduleInfo = null;
|
|
34
|
+
/**
|
|
35
|
+
* @param moduleName - Name of the module in the remote runtime (e.g., "pandas")
|
|
36
|
+
* @param client - ActionCable client connected to the remote runtime
|
|
37
|
+
* @param runtimeName - Name of the runtime (e.g., "rails") for debugging
|
|
38
|
+
*/
|
|
39
|
+
constructor(moduleName, client, runtimeName = 'remote') {
|
|
40
|
+
super(moduleName);
|
|
41
|
+
this.client = client;
|
|
42
|
+
this.runtimeName = runtimeName;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Initialize the module by discovering words from the remote runtime
|
|
46
|
+
*
|
|
47
|
+
* This must be called before the module is registered with an interpreter.
|
|
48
|
+
* It fetches the module metadata and creates WebSocketRemoteWord proxies for each word.
|
|
49
|
+
*/
|
|
50
|
+
async initialize() {
|
|
51
|
+
if (this.initialized) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
// Discover module info from remote runtime
|
|
56
|
+
this.moduleInfo = await this.client.getModuleInfo(this.name);
|
|
57
|
+
// Create WebSocketRemoteWord for each discovered word
|
|
58
|
+
for (const wordInfo of this.moduleInfo.words) {
|
|
59
|
+
const remoteWord = new WebSocketRemoteWord(wordInfo.name, this.client, this.runtimeName, this.name, wordInfo.stack_effect, wordInfo.description);
|
|
60
|
+
// Add as exportable word (visible when module is imported)
|
|
61
|
+
this.add_exportable_word(remoteWord);
|
|
62
|
+
}
|
|
63
|
+
this.initialized = true;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new Error(`Failed to initialize remote module '${this.name}' from ${this.runtimeName} runtime: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Override set_interp to ensure module is initialized
|
|
71
|
+
*/
|
|
72
|
+
set_interp(interp) {
|
|
73
|
+
if (!this.initialized) {
|
|
74
|
+
throw new Error(`WebSocketRemoteModule '${this.name}' must be initialized before being registered with an interpreter. Call await module.initialize() first.`);
|
|
75
|
+
}
|
|
76
|
+
super.set_interp(interp);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get the module metadata from the remote runtime
|
|
80
|
+
*/
|
|
81
|
+
getModuleInfo() {
|
|
82
|
+
return this.moduleInfo;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get runtime name for debugging
|
|
86
|
+
*/
|
|
87
|
+
getRuntimeName() {
|
|
88
|
+
return this.runtimeName;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check if module is initialized
|
|
92
|
+
*/
|
|
93
|
+
isInitialized() {
|
|
94
|
+
return this.initialized;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get count of discovered words
|
|
98
|
+
*/
|
|
99
|
+
getWordCount() {
|
|
100
|
+
return this.moduleInfo?.words?.length || 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=remote_module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote_module.js","sourceRoot":"","sources":["../../../src/websocket/remote_module.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,qBAAsB,SAAQ,MAAM;IACvC,MAAM,CAAoB;IAC1B,WAAW,CAAS;IACpB,WAAW,GAAY,KAAK,CAAC;IAC7B,UAAU,GAAsB,IAAI,CAAC;IAE7C;;;;OAIG;IACH,YAAY,UAAkB,EAAE,MAAyB,EAAE,cAAsB,QAAQ;QACvF,KAAK,CAAC,UAAU,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,2CAA2C;YAC3C,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE7D,sDAAsD;YACtD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBAC7C,MAAM,UAAU,GAAG,IAAI,mBAAmB,CACxC,QAAQ,CAAC,IAAI,EACb,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,IAAI,EACT,QAAQ,CAAC,YAAY,EACrB,QAAQ,CAAC,WAAW,CACrB,CAAC;gBAEF,2DAA2D;gBAC3D,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;YACvC,CAAC;YAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,uCAAuC,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,WAAW,aAAc,KAAe,CAAC,OAAO,EAAE,CAClH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,MAAmB;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,CAAC,IAAI,0GAA0G,CAC9I,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocketRemoteWord - Word that executes in a remote runtime via ActionCable
|
|
3
|
+
* Mirrors RemoteWord from gRPC implementation
|
|
4
|
+
*/
|
|
5
|
+
import { Word, RuntimeInfo } from '../forthic/module.js';
|
|
6
|
+
import { Interpreter } from '../forthic/interpreter.js';
|
|
7
|
+
import { ActionCableClient } from './action_cable_client.js';
|
|
8
|
+
/**
|
|
9
|
+
* WebSocketRemoteWord - Proxy word that delegates execution to a remote runtime
|
|
10
|
+
*
|
|
11
|
+
* When executed:
|
|
12
|
+
* 1. Captures current interpreter stack
|
|
13
|
+
* 2. Sends word name + stack to remote runtime via ActionCable
|
|
14
|
+
* 3. Replaces local stack with result stack from remote execution
|
|
15
|
+
*
|
|
16
|
+
* This allows seamless integration of remote runtime words
|
|
17
|
+
* into the local TypeScript interpreter.
|
|
18
|
+
*/
|
|
19
|
+
export declare class WebSocketRemoteWord extends Word {
|
|
20
|
+
private client;
|
|
21
|
+
private runtimeName;
|
|
22
|
+
private moduleName;
|
|
23
|
+
stackEffect: string;
|
|
24
|
+
description: string;
|
|
25
|
+
/**
|
|
26
|
+
* @param name - Word name (e.g., "DF_FROM_RECORDS")
|
|
27
|
+
* @param client - ActionCable client connected to remote runtime
|
|
28
|
+
* @param runtimeName - Name of remote runtime (e.g., "rails", "ruby")
|
|
29
|
+
* @param moduleName - Module name (e.g., "pandas")
|
|
30
|
+
* @param stackEffect - Stack notation (e.g., "( records:array -- df:DataFrame )")
|
|
31
|
+
* @param description - Human-readable description
|
|
32
|
+
*/
|
|
33
|
+
constructor(name: string, client: ActionCableClient, runtimeName: string, moduleName: string, stackEffect?: string, description?: string);
|
|
34
|
+
/**
|
|
35
|
+
* Execute word in remote runtime
|
|
36
|
+
*
|
|
37
|
+
* Captures entire stack, sends to remote runtime, and replaces stack with result.
|
|
38
|
+
*/
|
|
39
|
+
execute(interp: Interpreter): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Get runtime name for debugging/introspection
|
|
42
|
+
*/
|
|
43
|
+
getRuntimeName(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Get module name for debugging/introspection
|
|
46
|
+
*/
|
|
47
|
+
getModuleName(): string;
|
|
48
|
+
/**
|
|
49
|
+
* Get runtime execution information
|
|
50
|
+
* RemoteWords are runtime-specific and can only execute in their designated runtime
|
|
51
|
+
*/
|
|
52
|
+
getRuntimeInfo(): RuntimeInfo;
|
|
53
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocketRemoteWord - Word that executes in a remote runtime via ActionCable
|
|
3
|
+
* Mirrors RemoteWord from gRPC implementation
|
|
4
|
+
*/
|
|
5
|
+
import { Word } from '../forthic/module.js';
|
|
6
|
+
/**
|
|
7
|
+
* WebSocketRemoteWord - Proxy word that delegates execution to a remote runtime
|
|
8
|
+
*
|
|
9
|
+
* When executed:
|
|
10
|
+
* 1. Captures current interpreter stack
|
|
11
|
+
* 2. Sends word name + stack to remote runtime via ActionCable
|
|
12
|
+
* 3. Replaces local stack with result stack from remote execution
|
|
13
|
+
*
|
|
14
|
+
* This allows seamless integration of remote runtime words
|
|
15
|
+
* into the local TypeScript interpreter.
|
|
16
|
+
*/
|
|
17
|
+
export class WebSocketRemoteWord extends Word {
|
|
18
|
+
client;
|
|
19
|
+
runtimeName;
|
|
20
|
+
moduleName;
|
|
21
|
+
stackEffect;
|
|
22
|
+
description;
|
|
23
|
+
/**
|
|
24
|
+
* @param name - Word name (e.g., "DF_FROM_RECORDS")
|
|
25
|
+
* @param client - ActionCable client connected to remote runtime
|
|
26
|
+
* @param runtimeName - Name of remote runtime (e.g., "rails", "ruby")
|
|
27
|
+
* @param moduleName - Module name (e.g., "pandas")
|
|
28
|
+
* @param stackEffect - Stack notation (e.g., "( records:array -- df:DataFrame )")
|
|
29
|
+
* @param description - Human-readable description
|
|
30
|
+
*/
|
|
31
|
+
constructor(name, client, runtimeName, moduleName, stackEffect = '( -- )', description = '') {
|
|
32
|
+
super(name);
|
|
33
|
+
this.client = client;
|
|
34
|
+
this.runtimeName = runtimeName;
|
|
35
|
+
this.moduleName = moduleName;
|
|
36
|
+
this.stackEffect = stackEffect;
|
|
37
|
+
this.description = description;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execute word in remote runtime
|
|
41
|
+
*
|
|
42
|
+
* Captures entire stack, sends to remote runtime, and replaces stack with result.
|
|
43
|
+
*/
|
|
44
|
+
async execute(interp) {
|
|
45
|
+
try {
|
|
46
|
+
// Capture current stack state
|
|
47
|
+
const stack = interp.get_stack();
|
|
48
|
+
const stackItems = stack.get_items();
|
|
49
|
+
// Execute word in remote runtime
|
|
50
|
+
const resultStack = await this.client.executeWord(this.name, stackItems);
|
|
51
|
+
// Clear local stack and replace with result
|
|
52
|
+
while (interp.get_stack().length > 0) {
|
|
53
|
+
interp.stack_pop();
|
|
54
|
+
}
|
|
55
|
+
// Push all result items
|
|
56
|
+
for (const item of resultStack) {
|
|
57
|
+
interp.stack_push(item);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(`Error executing remote word ${this.moduleName}.${this.name} in ${this.runtimeName} runtime: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get runtime name for debugging/introspection
|
|
66
|
+
*/
|
|
67
|
+
getRuntimeName() {
|
|
68
|
+
return this.runtimeName;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get module name for debugging/introspection
|
|
72
|
+
*/
|
|
73
|
+
getModuleName() {
|
|
74
|
+
return this.moduleName;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get runtime execution information
|
|
78
|
+
* RemoteWords are runtime-specific and can only execute in their designated runtime
|
|
79
|
+
*/
|
|
80
|
+
getRuntimeInfo() {
|
|
81
|
+
return {
|
|
82
|
+
runtime: this.runtimeName,
|
|
83
|
+
isRemote: true,
|
|
84
|
+
isStandard: false,
|
|
85
|
+
availableIn: [this.runtimeName]
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=remote_word.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote_word.js","sourceRoot":"","sources":["../../../src/websocket/remote_word.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAe,MAAM,sBAAsB,CAAC;AAIzD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAoB,SAAQ,IAAI;IACnC,MAAM,CAAoB;IAC1B,WAAW,CAAS;IACpB,UAAU,CAAS;IACpB,WAAW,CAAS;IACpB,WAAW,CAAS;IAE3B;;;;;;;OAOG;IACH,YACE,IAAY,EACZ,MAAyB,EACzB,WAAmB,EACnB,UAAkB,EAClB,cAAsB,QAAQ,EAC9B,cAAsB,EAAE;QAExB,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,MAAmB;QAC/B,IAAI,CAAC;YACH,8BAA8B;YAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAErC,iCAAiC;YACjC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAEzE,4CAA4C;YAC5C,OAAO,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,CAAC;YAED,wBAAwB;YACxB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,+BAA+B,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,WAAW,aAAc,KAAe,CAAC,OAAO,EAAE,CAC1H,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,WAAW;YACzB,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;SAChC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocketRuntimeManager - Singleton for managing ActionCable connections to remote runtimes
|
|
3
|
+
*
|
|
4
|
+
* Provides centralized access to ActionCable clients for different runtimes
|
|
5
|
+
* Mirrors the gRPC RuntimeManager API for compatibility
|
|
6
|
+
*/
|
|
7
|
+
import { ActionCableClient, ActionCableClientConfig } from './action_cable_client.js';
|
|
8
|
+
/**
|
|
9
|
+
* WebSocketRuntimeManager - Manages ActionCable connections to remote Forthic runtimes
|
|
10
|
+
*/
|
|
11
|
+
export declare class WebSocketRuntimeManager {
|
|
12
|
+
private static instance;
|
|
13
|
+
private clients;
|
|
14
|
+
private constructor();
|
|
15
|
+
/**
|
|
16
|
+
* Get the singleton instance
|
|
17
|
+
*/
|
|
18
|
+
static getInstance(): WebSocketRuntimeManager;
|
|
19
|
+
/**
|
|
20
|
+
* Connect to a runtime and register the client
|
|
21
|
+
*
|
|
22
|
+
* @param runtimeName - Name of the runtime (e.g., "rails", "ruby")
|
|
23
|
+
* @param url - ActionCable URL (e.g., "ws://localhost:3000/cable")
|
|
24
|
+
* @param config - Optional additional configuration
|
|
25
|
+
* @returns ActionCableClient instance
|
|
26
|
+
*/
|
|
27
|
+
connectRuntime(runtimeName: string, url: string, config?: Partial<ActionCableClientConfig>): ActionCableClient;
|
|
28
|
+
/**
|
|
29
|
+
* Register an ActionCable client for a specific runtime
|
|
30
|
+
*
|
|
31
|
+
* @param runtimeName - Name of the runtime (e.g., "rails", "ruby")
|
|
32
|
+
* @param client - ActionCableClient instance connected to that runtime
|
|
33
|
+
*/
|
|
34
|
+
registerClient(runtimeName: string, client: ActionCableClient): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get the ActionCable client for a specific runtime
|
|
37
|
+
*
|
|
38
|
+
* @param runtimeName - Name of the runtime
|
|
39
|
+
* @returns ActionCableClient instance or undefined if not registered
|
|
40
|
+
*/
|
|
41
|
+
getClient(runtimeName: string): ActionCableClient | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Check if a runtime has a registered client
|
|
44
|
+
*
|
|
45
|
+
* @param runtimeName - Name of the runtime
|
|
46
|
+
* @returns True if client is registered
|
|
47
|
+
*/
|
|
48
|
+
hasClient(runtimeName: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Get all registered runtime names
|
|
51
|
+
*
|
|
52
|
+
* @returns Array of runtime names
|
|
53
|
+
*/
|
|
54
|
+
getRegisteredRuntimes(): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Disconnect a specific runtime
|
|
57
|
+
*
|
|
58
|
+
* @param runtimeName - Name of the runtime to disconnect
|
|
59
|
+
*/
|
|
60
|
+
disconnectRuntime(runtimeName: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Clear all registered clients (useful for testing)
|
|
63
|
+
*/
|
|
64
|
+
clearAll(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Reset the singleton (useful for testing)
|
|
67
|
+
*/
|
|
68
|
+
static reset(): void;
|
|
69
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocketRuntimeManager - Singleton for managing ActionCable connections to remote runtimes
|
|
3
|
+
*
|
|
4
|
+
* Provides centralized access to ActionCable clients for different runtimes
|
|
5
|
+
* Mirrors the gRPC RuntimeManager API for compatibility
|
|
6
|
+
*/
|
|
7
|
+
import { ActionCableClient } from './action_cable_client.js';
|
|
8
|
+
/**
|
|
9
|
+
* WebSocketRuntimeManager - Manages ActionCable connections to remote Forthic runtimes
|
|
10
|
+
*/
|
|
11
|
+
export class WebSocketRuntimeManager {
|
|
12
|
+
static instance = null;
|
|
13
|
+
clients;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.clients = new Map();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the singleton instance
|
|
19
|
+
*/
|
|
20
|
+
static getInstance() {
|
|
21
|
+
if (!WebSocketRuntimeManager.instance) {
|
|
22
|
+
WebSocketRuntimeManager.instance = new WebSocketRuntimeManager();
|
|
23
|
+
}
|
|
24
|
+
return WebSocketRuntimeManager.instance;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Connect to a runtime and register the client
|
|
28
|
+
*
|
|
29
|
+
* @param runtimeName - Name of the runtime (e.g., "rails", "ruby")
|
|
30
|
+
* @param url - ActionCable URL (e.g., "ws://localhost:3000/cable")
|
|
31
|
+
* @param config - Optional additional configuration
|
|
32
|
+
* @returns ActionCableClient instance
|
|
33
|
+
*/
|
|
34
|
+
connectRuntime(runtimeName, url, config) {
|
|
35
|
+
// Create a new client for the runtime
|
|
36
|
+
const client = new ActionCableClient({ url, ...config });
|
|
37
|
+
// Register it
|
|
38
|
+
this.clients.set(runtimeName, client);
|
|
39
|
+
return client;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register an ActionCable client for a specific runtime
|
|
43
|
+
*
|
|
44
|
+
* @param runtimeName - Name of the runtime (e.g., "rails", "ruby")
|
|
45
|
+
* @param client - ActionCableClient instance connected to that runtime
|
|
46
|
+
*/
|
|
47
|
+
registerClient(runtimeName, client) {
|
|
48
|
+
this.clients.set(runtimeName, client);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the ActionCable client for a specific runtime
|
|
52
|
+
*
|
|
53
|
+
* @param runtimeName - Name of the runtime
|
|
54
|
+
* @returns ActionCableClient instance or undefined if not registered
|
|
55
|
+
*/
|
|
56
|
+
getClient(runtimeName) {
|
|
57
|
+
return this.clients.get(runtimeName);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if a runtime has a registered client
|
|
61
|
+
*
|
|
62
|
+
* @param runtimeName - Name of the runtime
|
|
63
|
+
* @returns True if client is registered
|
|
64
|
+
*/
|
|
65
|
+
hasClient(runtimeName) {
|
|
66
|
+
return this.clients.has(runtimeName);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get all registered runtime names
|
|
70
|
+
*
|
|
71
|
+
* @returns Array of runtime names
|
|
72
|
+
*/
|
|
73
|
+
getRegisteredRuntimes() {
|
|
74
|
+
return Array.from(this.clients.keys());
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Disconnect a specific runtime
|
|
78
|
+
*
|
|
79
|
+
* @param runtimeName - Name of the runtime to disconnect
|
|
80
|
+
*/
|
|
81
|
+
disconnectRuntime(runtimeName) {
|
|
82
|
+
const client = this.clients.get(runtimeName);
|
|
83
|
+
if (client) {
|
|
84
|
+
client.close();
|
|
85
|
+
this.clients.delete(runtimeName);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Clear all registered clients (useful for testing)
|
|
90
|
+
*/
|
|
91
|
+
clearAll() {
|
|
92
|
+
// Close all clients
|
|
93
|
+
for (const client of this.clients.values()) {
|
|
94
|
+
client.close();
|
|
95
|
+
}
|
|
96
|
+
this.clients.clear();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Reset the singleton (useful for testing)
|
|
100
|
+
*/
|
|
101
|
+
static reset() {
|
|
102
|
+
if (WebSocketRuntimeManager.instance) {
|
|
103
|
+
WebSocketRuntimeManager.instance.clearAll();
|
|
104
|
+
WebSocketRuntimeManager.instance = null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=runtime_manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime_manager.js","sourceRoot":"","sources":["../../../src/websocket/runtime_manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,iBAAiB,EAA2B,MAAM,0BAA0B,CAAC;AAEtF;;GAEG;AACH,MAAM,OAAO,uBAAuB;IAC1B,MAAM,CAAC,QAAQ,GAAmC,IAAI,CAAC;IACvD,OAAO,CAAiC;IAEhD;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EAAE,CAAC;YACtC,uBAAuB,CAAC,QAAQ,GAAG,IAAI,uBAAuB,EAAE,CAAC;QACnE,CAAC;QACD,OAAO,uBAAuB,CAAC,QAAQ,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CACZ,WAAmB,EACnB,GAAW,EACX,MAAyC;QAEzC,sCAAsC;QACtC,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAEzD,cAAc;QACd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAEtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,WAAmB,EAAE,MAAyB;QAC3D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,WAAmB;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,WAAmB;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,qBAAqB;QACnB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,iBAAiB,CAAC,WAAmB;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,oBAAoB;QACpB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK;QACV,IAAI,uBAAuB,CAAC,QAAQ,EAAE,CAAC;YACrC,uBAAuB,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC5C,uBAAuB,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1C,CAAC;IACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
/**
|
|
3
|
-
* Registry metadata types for stack objects and class instances.
|
|
4
|
-
*/
|
|
5
|
-
type StackObjectMetadata = {
|
|
6
|
-
objectType: "stackObject";
|
|
7
|
-
stackObjectType: string;
|
|
8
|
-
className?: undefined;
|
|
9
|
-
OriginalClass?: undefined;
|
|
10
|
-
} | {
|
|
11
|
-
objectType: "class";
|
|
12
|
-
OriginalClass: new (...args: any[]) => any;
|
|
13
|
-
className: string;
|
|
14
|
-
stackObjectType?: undefined;
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Track metadata for schema comparison in tests and documentation.
|
|
18
|
-
* Only required for schemas that can't be compared out of the box,
|
|
19
|
-
* like custom schemas or instanceof schemas.
|
|
20
|
-
*/
|
|
21
|
-
export declare const stackObjectRegistry: z.core.$ZodRegistry<StackObjectMetadata, z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
22
|
-
/**
|
|
23
|
-
* Creates a Zod schema for stack objects that have a stackObjectType property.
|
|
24
|
-
* This is a helper to reduce boilerplate when creating custom stack object schemas.
|
|
25
|
-
* It also ensures the schema is registered in stackObjectRegistry, which enables
|
|
26
|
-
* proper type string generation in stack effects.
|
|
27
|
-
*
|
|
28
|
-
* Use this instead of z.custom() directly for stack objects.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* interface StackEmail {
|
|
33
|
-
* stackObjectType: "email";
|
|
34
|
-
* to: string;
|
|
35
|
-
* subject: string;
|
|
36
|
-
* body: string;
|
|
37
|
-
* }
|
|
38
|
-
*
|
|
39
|
-
* const stackEmailSchema = createStackObjectSchema<StackEmail>("email");
|
|
40
|
-
*
|
|
41
|
-
* // Use in stack effect:
|
|
42
|
-
* @ForthicWord(se`(email:${stackEmailSchema} -- sent:${z.boolean()})`, "Send email")
|
|
43
|
-
* async SEND(email: StackEmail): Promise<boolean> { ... }
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export declare function createStackObjectSchema<T extends {
|
|
47
|
-
stackObjectType: string;
|
|
48
|
-
}>(stackObjectType: string, errorMessage?: string): z.ZodCustom<T>;
|
|
49
|
-
/**
|
|
50
|
-
* Creates a Zod instanceof schema with automatic metadata registration.
|
|
51
|
-
* This ensures the schema is registered in stackObjectRegistry, which enables
|
|
52
|
-
* proper type string generation in stack effects.
|
|
53
|
-
*
|
|
54
|
-
* Use this instead of z.instanceof() directly.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* import { Temporal } from "temporal-polyfill";
|
|
59
|
-
*
|
|
60
|
-
* const plainDateSchema = createInstanceOfSchema(Temporal.PlainDate);
|
|
61
|
-
*
|
|
62
|
-
* // Use in stack effect:
|
|
63
|
-
* @ForthicWord(se`(date:${plainDateSchema} -- formatted:${z.string()})`, "Format date")
|
|
64
|
-
* async FORMAT(date: Temporal.PlainDate): Promise<string> { ... }
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
export declare function createInstanceOfSchema<T extends abstract new (...args: any[]) => any>(ClassToSchematize: T,
|
|
68
|
-
/** If not passed, falls back to class.name */
|
|
69
|
-
className?: string): z.ZodType<InstanceType<T>>;
|
|
70
|
-
export {};
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.stackObjectRegistry = void 0;
|
|
4
|
-
exports.createStackObjectSchema = createStackObjectSchema;
|
|
5
|
-
exports.createInstanceOfSchema = createInstanceOfSchema;
|
|
6
|
-
const zod_1 = require("zod");
|
|
7
|
-
/**
|
|
8
|
-
* Track metadata for schema comparison in tests and documentation.
|
|
9
|
-
* Only required for schemas that can't be compared out of the box,
|
|
10
|
-
* like custom schemas or instanceof schemas.
|
|
11
|
-
*/
|
|
12
|
-
exports.stackObjectRegistry = zod_1.z.registry();
|
|
13
|
-
/**
|
|
14
|
-
* Creates a Zod schema for stack objects that have a stackObjectType property.
|
|
15
|
-
* This is a helper to reduce boilerplate when creating custom stack object schemas.
|
|
16
|
-
* It also ensures the schema is registered in stackObjectRegistry, which enables
|
|
17
|
-
* proper type string generation in stack effects.
|
|
18
|
-
*
|
|
19
|
-
* Use this instead of z.custom() directly for stack objects.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* interface StackEmail {
|
|
24
|
-
* stackObjectType: "email";
|
|
25
|
-
* to: string;
|
|
26
|
-
* subject: string;
|
|
27
|
-
* body: string;
|
|
28
|
-
* }
|
|
29
|
-
*
|
|
30
|
-
* const stackEmailSchema = createStackObjectSchema<StackEmail>("email");
|
|
31
|
-
*
|
|
32
|
-
* // Use in stack effect:
|
|
33
|
-
* @ForthicWord(se`(email:${stackEmailSchema} -- sent:${z.boolean()})`, "Send email")
|
|
34
|
-
* async SEND(email: StackEmail): Promise<boolean> { ... }
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
function createStackObjectSchema(stackObjectType, errorMessage) {
|
|
38
|
-
const schema = zod_1.z.custom((maybeStackObject) => maybeStackObject?.stackObjectType === stackObjectType, errorMessage ?? `expected ${stackObjectType} stackObjectType`);
|
|
39
|
-
// Register schema with metadata
|
|
40
|
-
exports.stackObjectRegistry.add(schema, {
|
|
41
|
-
objectType: "stackObject",
|
|
42
|
-
stackObjectType,
|
|
43
|
-
});
|
|
44
|
-
return schema;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Creates a Zod instanceof schema with automatic metadata registration.
|
|
48
|
-
* This ensures the schema is registered in stackObjectRegistry, which enables
|
|
49
|
-
* proper type string generation in stack effects.
|
|
50
|
-
*
|
|
51
|
-
* Use this instead of z.instanceof() directly.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* import { Temporal } from "temporal-polyfill";
|
|
56
|
-
*
|
|
57
|
-
* const plainDateSchema = createInstanceOfSchema(Temporal.PlainDate);
|
|
58
|
-
*
|
|
59
|
-
* // Use in stack effect:
|
|
60
|
-
* @ForthicWord(se`(date:${plainDateSchema} -- formatted:${z.string()})`, "Format date")
|
|
61
|
-
* async FORMAT(date: Temporal.PlainDate): Promise<string> { ... }
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
function createInstanceOfSchema(ClassToSchematize,
|
|
65
|
-
/** If not passed, falls back to class.name */
|
|
66
|
-
className) {
|
|
67
|
-
const schema = zod_1.z.instanceof(ClassToSchematize);
|
|
68
|
-
// Register schema with metadata
|
|
69
|
-
const resolvedClassName = className ?? ClassToSchematize.name;
|
|
70
|
-
exports.stackObjectRegistry.add(schema, {
|
|
71
|
-
objectType: "class",
|
|
72
|
-
OriginalClass: ClassToSchematize,
|
|
73
|
-
className: resolvedClassName,
|
|
74
|
-
});
|
|
75
|
-
return schema;
|
|
76
|
-
}
|
|
77
|
-
//# sourceMappingURL=schemaUtils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schemaUtils.js","sourceRoot":"","sources":["../../../../src/forthic/decorators/schemaUtils.ts"],"names":[],"mappings":";;;AAkDA,0DAgBC;AAoBD,wDAgBC;AAtGD,6BAAwB;AAmBxB;;;;GAIG;AACU,QAAA,mBAAmB,GAAG,OAAC,CAAC,QAAQ,EAAuB,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,uBAAuB,CACrC,eAAuB,EACvB,YAAqB;IAErB,MAAM,MAAM,GAAG,OAAC,CAAC,MAAM,CACrB,CAAC,gBAAgB,EAAE,EAAE,CAAE,gBAAkC,EAAE,eAAe,KAAK,eAAe,EAC9F,YAAY,IAAI,YAAY,eAAe,kBAAkB,CAC9D,CAAC;IAEF,gCAAgC;IAChC,2BAAmB,CAAC,GAAG,CAAC,MAAM,EAAE;QAC9B,UAAU,EAAE,aAAa;QACzB,eAAe;KAChB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,sBAAsB,CACpC,iBAAoB;AACpB,8CAA8C;AAC9C,SAAkB;IAElB,MAAM,MAAM,GAAG,OAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAE/C,gCAAgC;IAChC,MAAM,iBAAiB,GAAG,SAAS,IAAI,iBAAiB,CAAC,IAAI,CAAC;IAC9D,2BAAmB,CAAC,GAAG,CAAC,MAAM,EAAE;QAC9B,UAAU,EAAE,OAAO;QACnB,aAAa,EAAE,iBAAiB;QAChC,SAAS,EAAE,iBAAiB;KAC7B,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|