@forthix/forthic 0.7.0 → 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.
Files changed (95) hide show
  1. package/dist/cjs/common/type_utils.js.map +1 -1
  2. package/dist/cjs/forthic/interpreter.d.ts +2 -1
  3. package/dist/cjs/forthic/interpreter.js +10 -0
  4. package/dist/cjs/forthic/interpreter.js.map +1 -1
  5. package/dist/cjs/forthic/literals.d.ts +0 -1
  6. package/dist/cjs/forthic/literals.js +14 -15
  7. package/dist/cjs/forthic/literals.js.map +1 -1
  8. package/dist/cjs/forthic/modules/standard/datetime_module.d.ts +0 -1
  9. package/dist/cjs/forthic/modules/standard/datetime_module.js +19 -20
  10. package/dist/cjs/forthic/modules/standard/datetime_module.js.map +1 -1
  11. package/dist/cjs/forthic/utils.d.ts +0 -1
  12. package/dist/cjs/forthic/utils.js +1 -2
  13. package/dist/cjs/forthic/utils.js.map +1 -1
  14. package/dist/cjs/grpc/serializer.js +3 -4
  15. package/dist/cjs/grpc/serializer.js.map +1 -1
  16. package/dist/cjs/grpc/server.test.d.ts +1 -0
  17. package/dist/cjs/grpc/server.test.js +156 -0
  18. package/dist/cjs/grpc/server.test.js.map +1 -0
  19. package/dist/cjs/grpc/temporal_utils.d.ts +36 -0
  20. package/dist/cjs/grpc/temporal_utils.js +80 -0
  21. package/dist/cjs/grpc/temporal_utils.js.map +1 -0
  22. package/dist/cjs/test-setup.d.ts +1 -0
  23. package/dist/cjs/test-setup.js +4 -0
  24. package/dist/cjs/test-setup.js.map +1 -0
  25. package/dist/cjs/websocket/action_cable_client.d.ts +106 -0
  26. package/dist/cjs/websocket/action_cable_client.js +269 -0
  27. package/dist/cjs/websocket/action_cable_client.js.map +1 -0
  28. package/dist/cjs/websocket/client.d.ts +103 -0
  29. package/dist/cjs/websocket/client.js +266 -0
  30. package/dist/cjs/websocket/client.js.map +1 -0
  31. package/dist/cjs/websocket/remote_module.d.ts +68 -0
  32. package/dist/cjs/websocket/remote_module.js +107 -0
  33. package/dist/cjs/websocket/remote_module.js.map +1 -0
  34. package/dist/cjs/websocket/remote_word.d.ts +53 -0
  35. package/dist/cjs/websocket/remote_word.js +93 -0
  36. package/dist/cjs/websocket/remote_word.js.map +1 -0
  37. package/dist/cjs/websocket/runtime_manager.d.ts +69 -0
  38. package/dist/cjs/websocket/runtime_manager.js +112 -0
  39. package/dist/cjs/websocket/runtime_manager.js.map +1 -0
  40. package/dist/cjs/websocket/serializer.js +3 -4
  41. package/dist/cjs/websocket/serializer.js.map +1 -1
  42. package/dist/esm/common/type_utils.js.map +1 -1
  43. package/dist/esm/forthic/interpreter.d.ts +2 -1
  44. package/dist/esm/forthic/interpreter.js +11 -1
  45. package/dist/esm/forthic/interpreter.js.map +1 -1
  46. package/dist/esm/forthic/literals.d.ts +0 -1
  47. package/dist/esm/forthic/literals.js +0 -1
  48. package/dist/esm/forthic/literals.js.map +1 -1
  49. package/dist/esm/forthic/modules/standard/datetime_module.d.ts +0 -1
  50. package/dist/esm/forthic/modules/standard/datetime_module.js +0 -1
  51. package/dist/esm/forthic/modules/standard/datetime_module.js.map +1 -1
  52. package/dist/esm/forthic/utils.d.ts +0 -1
  53. package/dist/esm/forthic/utils.js +0 -1
  54. package/dist/esm/forthic/utils.js.map +1 -1
  55. package/dist/esm/grpc/serializer.js +0 -1
  56. package/dist/esm/grpc/serializer.js.map +1 -1
  57. package/dist/esm/grpc/server.test.d.ts +1 -0
  58. package/dist/esm/grpc/server.test.js +121 -0
  59. package/dist/esm/grpc/server.test.js.map +1 -0
  60. package/dist/esm/grpc/temporal_utils.d.ts +36 -0
  61. package/dist/esm/grpc/temporal_utils.js +72 -0
  62. package/dist/esm/grpc/temporal_utils.js.map +1 -0
  63. package/dist/esm/test-setup.d.ts +1 -0
  64. package/dist/esm/test-setup.js +2 -0
  65. package/dist/esm/test-setup.js.map +1 -0
  66. package/dist/esm/websocket/action_cable_client.d.ts +106 -0
  67. package/dist/esm/websocket/action_cable_client.js +265 -0
  68. package/dist/esm/websocket/action_cable_client.js.map +1 -0
  69. package/dist/esm/websocket/client.d.ts +103 -0
  70. package/dist/esm/websocket/client.js +262 -0
  71. package/dist/esm/websocket/client.js.map +1 -0
  72. package/dist/esm/websocket/remote_module.d.ts +68 -0
  73. package/dist/esm/websocket/remote_module.js +103 -0
  74. package/dist/esm/websocket/remote_module.js.map +1 -0
  75. package/dist/esm/websocket/remote_word.d.ts +53 -0
  76. package/dist/esm/websocket/remote_word.js +89 -0
  77. package/dist/esm/websocket/remote_word.js.map +1 -0
  78. package/dist/esm/websocket/runtime_manager.d.ts +69 -0
  79. package/dist/esm/websocket/runtime_manager.js +108 -0
  80. package/dist/esm/websocket/runtime_manager.js.map +1 -0
  81. package/dist/esm/websocket/serializer.js +0 -1
  82. package/dist/esm/websocket/serializer.js.map +1 -1
  83. package/package.json +3 -2
  84. package/dist/cjs/forthic/decorators/schemaUtils.d.ts +0 -70
  85. package/dist/cjs/forthic/decorators/schemaUtils.js +0 -77
  86. package/dist/cjs/forthic/decorators/schemaUtils.js.map +0 -1
  87. package/dist/cjs/forthic/decorators/stackEffect.d.ts +0 -63
  88. package/dist/cjs/forthic/decorators/stackEffect.js +0 -179
  89. package/dist/cjs/forthic/decorators/stackEffect.js.map +0 -1
  90. package/dist/esm/forthic/decorators/schemaUtils.d.ts +0 -70
  91. package/dist/esm/forthic/decorators/schemaUtils.js +0 -72
  92. package/dist/esm/forthic/decorators/schemaUtils.js.map +0 -1
  93. package/dist/esm/forthic/decorators/stackEffect.d.ts +0 -63
  94. package/dist/esm/forthic/decorators/stackEffect.js +0 -174
  95. package/dist/esm/forthic/decorators/stackEffect.js.map +0 -1
@@ -3,7 +3,6 @@
3
3
  * Converts JavaScript values to/from protobuf StackValue format
4
4
  * Uses shared type detection from common/type_utils
5
5
  */
6
- import { Temporal } from "temporal-polyfill";
7
6
  import { getForthicType } from "../common/type_utils.js";
8
7
  /**
9
8
  * Serialize a JavaScript value to a StackValue protobuf message
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../../src/grpc/serializer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../../src/grpc/serializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Phase 11.1: Basic server tests
3
+ * Verify that the TypeScript gRPC server can start and listen on port 50052
4
+ */
5
+ import { serve } from './server';
6
+ import * as grpc from '@grpc/grpc-js';
7
+ import * as protoLoader from '@grpc/proto-loader';
8
+ import * as path from 'path';
9
+ describe('TypeScript gRPC Server', () => {
10
+ let server = null;
11
+ const TEST_PORT = 50053; // Use different port to avoid conflicts
12
+ afterEach(async () => {
13
+ // Clean up server if running
14
+ if (server) {
15
+ await new Promise((resolve) => {
16
+ server.tryShutdown(() => {
17
+ resolve();
18
+ });
19
+ });
20
+ server = null;
21
+ }
22
+ });
23
+ test('server starts and listens on specified port', async () => {
24
+ // Start server in background (don't await)
25
+ const serverPromise = serve(TEST_PORT);
26
+ // Give server time to start
27
+ await new Promise((resolve) => setTimeout(resolve, 1000));
28
+ // Try to connect with a client
29
+ const possiblePaths = [
30
+ path.join(__dirname, '../../../../forthic/protos/forthic_runtime.proto'),
31
+ path.join(__dirname, '../../../forthic/protos/forthic_runtime.proto'),
32
+ path.join(process.cwd(), '../forthic/protos/forthic_runtime.proto'),
33
+ ];
34
+ let PROTO_PATH = possiblePaths[0];
35
+ const fs = require('fs');
36
+ for (const tryPath of possiblePaths) {
37
+ if (fs.existsSync(tryPath)) {
38
+ PROTO_PATH = tryPath;
39
+ break;
40
+ }
41
+ }
42
+ const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
43
+ keepCase: true,
44
+ longs: Number,
45
+ enums: String,
46
+ defaults: true,
47
+ oneofs: true,
48
+ });
49
+ const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
50
+ const forthicProto = protoDescriptor.forthic;
51
+ // Create client
52
+ const client = new forthicProto.ForthicRuntime(`localhost:${TEST_PORT}`, grpc.credentials.createInsecure());
53
+ // Test that we can connect by calling ListModules
54
+ const response = await new Promise((resolve, reject) => {
55
+ client.ListModules({}, (error, response) => {
56
+ if (error) {
57
+ reject(error);
58
+ }
59
+ else {
60
+ resolve(response);
61
+ }
62
+ });
63
+ });
64
+ // Should succeed with empty module list (no TS-specific modules yet)
65
+ expect(response).toBeDefined();
66
+ expect(response.modules).toBeDefined();
67
+ expect(Array.isArray(response.modules)).toBe(true);
68
+ // Clean up client
69
+ grpc.closeClient(client);
70
+ }, 10000); // 10 second timeout
71
+ test('server can execute simple stdlib word', async () => {
72
+ // Start server
73
+ const serverPromise = serve(TEST_PORT);
74
+ await new Promise((resolve) => setTimeout(resolve, 1000));
75
+ // Load proto
76
+ const possiblePaths = [
77
+ path.join(__dirname, '../../../../forthic/protos/forthic_runtime.proto'),
78
+ path.join(__dirname, '../../../forthic/protos/forthic_runtime.proto'),
79
+ path.join(process.cwd(), '../forthic/protos/forthic_runtime.proto'),
80
+ ];
81
+ let PROTO_PATH = possiblePaths[0];
82
+ const fs = require('fs');
83
+ for (const tryPath of possiblePaths) {
84
+ if (fs.existsSync(tryPath)) {
85
+ PROTO_PATH = tryPath;
86
+ break;
87
+ }
88
+ }
89
+ const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
90
+ keepCase: true,
91
+ longs: Number,
92
+ enums: String,
93
+ defaults: true,
94
+ oneofs: true,
95
+ });
96
+ const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
97
+ const forthicProto = protoDescriptor.forthic;
98
+ const client = new forthicProto.ForthicRuntime(`localhost:${TEST_PORT}`, grpc.credentials.createInsecure());
99
+ // Execute DUP word (duplicates top stack item)
100
+ const response = await new Promise((resolve, reject) => {
101
+ client.ExecuteWord({
102
+ word_name: 'DUP',
103
+ stack: [{ int_value: 42 }],
104
+ }, (error, response) => {
105
+ if (error) {
106
+ reject(error);
107
+ }
108
+ else {
109
+ resolve(response);
110
+ }
111
+ });
112
+ });
113
+ // Should have [42, 42] on stack
114
+ expect(response.result_stack).toBeDefined();
115
+ expect(response.result_stack.length).toBe(2);
116
+ expect(response.result_stack[0].int_value).toBe(42);
117
+ expect(response.result_stack[1].int_value).toBe(42);
118
+ grpc.closeClient(client);
119
+ }, 10000);
120
+ });
121
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../../src/grpc/server.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Temporal Type Utilities
3
+ *
4
+ * Provides duck-typing helpers for checking Temporal types.
5
+ * Uses duck typing instead of instanceof to avoid issues with multiple
6
+ * instances of temporal-polyfill being loaded.
7
+ */
8
+ /**
9
+ * Check if a value is a Temporal.PlainDate
10
+ * PlainDate has year, month, day properties but no hour property
11
+ */
12
+ export declare function isPlainDate(value: any): boolean;
13
+ /**
14
+ * Check if a value is a Temporal.Instant
15
+ * Instant has epochNanoseconds property as a bigint
16
+ */
17
+ export declare function isInstant(value: any): boolean;
18
+ /**
19
+ * Check if a value is a Temporal.ZonedDateTime
20
+ * ZonedDateTime has a timeZoneId property
21
+ */
22
+ export declare function isZonedDateTime(value: any): boolean;
23
+ /**
24
+ * Check if a value is a Temporal.PlainTime
25
+ * PlainTime has hour and minute properties but no year
26
+ */
27
+ export declare function isPlainTime(value: any): boolean;
28
+ /**
29
+ * Check if a value is a Temporal.PlainDateTime
30
+ * PlainDateTime has year, month, day, hour properties but no timeZoneId
31
+ */
32
+ export declare function isPlainDateTime(value: any): boolean;
33
+ /**
34
+ * Check if a value is any Temporal type
35
+ */
36
+ export declare function isTemporal(value: any): boolean;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Temporal Type Utilities
3
+ *
4
+ * Provides duck-typing helpers for checking Temporal types.
5
+ * Uses duck typing instead of instanceof to avoid issues with multiple
6
+ * instances of temporal-polyfill being loaded.
7
+ */
8
+ /**
9
+ * Check if a value is a Temporal.PlainDate
10
+ * PlainDate has year, month, day properties but no hour property
11
+ */
12
+ export function isPlainDate(value) {
13
+ return value && typeof value === 'object' &&
14
+ typeof value.year === 'number' &&
15
+ typeof value.month === 'number' &&
16
+ typeof value.day === 'number' &&
17
+ typeof value.toString === 'function' &&
18
+ !value.hour; // PlainDate doesn't have hour
19
+ }
20
+ /**
21
+ * Check if a value is a Temporal.Instant
22
+ * Instant has epochNanoseconds property as a bigint
23
+ */
24
+ export function isInstant(value) {
25
+ return value && typeof value === 'object' &&
26
+ typeof value.epochNanoseconds === 'bigint' &&
27
+ typeof value.toString === 'function';
28
+ }
29
+ /**
30
+ * Check if a value is a Temporal.ZonedDateTime
31
+ * ZonedDateTime has a timeZoneId property
32
+ */
33
+ export function isZonedDateTime(value) {
34
+ return value && typeof value === 'object' &&
35
+ typeof value.timeZoneId === 'string' &&
36
+ typeof value.toString === 'function';
37
+ }
38
+ /**
39
+ * Check if a value is a Temporal.PlainTime
40
+ * PlainTime has hour and minute properties but no year
41
+ */
42
+ export function isPlainTime(value) {
43
+ return value && typeof value === 'object' &&
44
+ typeof value.hour === 'number' &&
45
+ typeof value.minute === 'number' &&
46
+ typeof value.toString === 'function' &&
47
+ !value.year; // PlainTime doesn't have year
48
+ }
49
+ /**
50
+ * Check if a value is a Temporal.PlainDateTime
51
+ * PlainDateTime has year, month, day, hour properties but no timeZoneId
52
+ */
53
+ export function isPlainDateTime(value) {
54
+ return value && typeof value === 'object' &&
55
+ typeof value.year === 'number' &&
56
+ typeof value.month === 'number' &&
57
+ typeof value.day === 'number' &&
58
+ typeof value.hour === 'number' &&
59
+ typeof value.toString === 'function' &&
60
+ !value.timeZoneId; // PlainDateTime doesn't have timeZoneId
61
+ }
62
+ /**
63
+ * Check if a value is any Temporal type
64
+ */
65
+ export function isTemporal(value) {
66
+ return isPlainDate(value) ||
67
+ isInstant(value) ||
68
+ isZonedDateTime(value) ||
69
+ isPlainTime(value) ||
70
+ isPlainDateTime(value);
71
+ }
72
+ //# sourceMappingURL=temporal_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal_utils.js","sourceRoot":"","sources":["../../../src/grpc/temporal_utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAU;IACpC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAClC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC/B,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAC7B,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU;QACpC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAE,8BAA8B;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAU;IAClC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAClC,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ;QAC1C,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAU;IACxC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAClC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAU;IACpC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAClC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChC,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU;QACpC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAE,8BAA8B;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAU;IACxC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAClC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC/B,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAC7B,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU;QACpC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAE,wCAAwC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAU;IACnC,OAAO,WAAW,CAAC,KAAK,CAAC;QAClB,SAAS,CAAC,KAAK,CAAC;QAChB,eAAe,CAAC,KAAK,CAAC;QACtB,WAAW,CAAC,KAAK,CAAC;QAClB,eAAe,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1 @@
1
+ import "temporal-polyfill/global";
@@ -0,0 +1,2 @@
1
+ import "temporal-polyfill/global";
2
+ //# sourceMappingURL=test-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-setup.js","sourceRoot":"","sources":["../../src/test-setup.ts"],"names":[],"mappings":"AAAA,OAAO,0BAA0B,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * ActionCable Client for Forthic
3
+ * Browser-compatible client that mirrors GrpcClient API
4
+ * Specifically designed for Rails ActionCable WebSocket protocol
5
+ */
6
+ import { StackValue } from './serializer.js';
7
+ export interface ModuleSummary {
8
+ name: string;
9
+ description: string;
10
+ word_count: number;
11
+ }
12
+ export interface WordInfo {
13
+ name: string;
14
+ stack_effect: string;
15
+ description: string;
16
+ }
17
+ export interface ModuleInfo {
18
+ module_name: string;
19
+ words: WordInfo[];
20
+ }
21
+ export interface ProgressUpdate {
22
+ step: number;
23
+ total_steps: number;
24
+ current_word: string;
25
+ message?: string;
26
+ partial_stack?: StackValue[];
27
+ }
28
+ export interface ActionCableClientConfig {
29
+ url: string;
30
+ timezone?: string;
31
+ reconnect?: boolean;
32
+ reconnectDelay?: number;
33
+ channel?: string;
34
+ }
35
+ /**
36
+ * ActionCable client for executing words in remote Forthic runtimes
37
+ * Mirrors the GrpcClient API for compatibility
38
+ * Uses Rails ActionCable WebSocket protocol
39
+ */
40
+ export declare class ActionCableClient {
41
+ private ws?;
42
+ private config;
43
+ private pendingRequests;
44
+ private messageId;
45
+ private connected;
46
+ private connectionPromise?;
47
+ constructor(config: ActionCableClientConfig);
48
+ /**
49
+ * Connect to the WebSocket server
50
+ */
51
+ private connect;
52
+ /**
53
+ * Handle incoming WebSocket messages
54
+ */
55
+ private handleMessage;
56
+ /**
57
+ * Generate next message ID
58
+ */
59
+ private nextMessageId;
60
+ /**
61
+ * Send a request and wait for response
62
+ * @template T The expected result type (the value of the `result` field)
63
+ */
64
+ private sendRequest;
65
+ /**
66
+ * Send a streaming request with progress callbacks
67
+ * @template T The expected result type (the value of the `result` field)
68
+ */
69
+ private sendStreamingRequest;
70
+ /**
71
+ * Ensure WebSocket is connected
72
+ */
73
+ private ensureConnected;
74
+ /**
75
+ * Execute a word in the remote runtime
76
+ * Mirrors GrpcClient.executeWord
77
+ */
78
+ executeWord(word: string, stack: any[]): Promise<any[]>;
79
+ /**
80
+ * Execute a sequence of words (batched execution)
81
+ * Mirrors GrpcClient.executeSequence
82
+ */
83
+ executeSequence(words: string[], stack: any[]): Promise<any[]>;
84
+ /**
85
+ * List available runtime-specific modules
86
+ * Mirrors GrpcClient.listModules
87
+ */
88
+ listModules(): Promise<ModuleSummary[]>;
89
+ /**
90
+ * Get detailed information about a specific module
91
+ * Mirrors GrpcClient.getModuleInfo
92
+ */
93
+ getModuleInfo(moduleName: string): Promise<ModuleInfo>;
94
+ /**
95
+ * Execute code with streaming progress updates (NEW capability)
96
+ */
97
+ streamingExecute(code: string, stack: any[], onProgress?: (progress: ProgressUpdate) => void): Promise<any[]>;
98
+ /**
99
+ * Close the WebSocket connection
100
+ */
101
+ close(): void;
102
+ /**
103
+ * Check if the client is connected
104
+ */
105
+ isConnected(): boolean;
106
+ }
@@ -0,0 +1,265 @@
1
+ /**
2
+ * ActionCable Client for Forthic
3
+ * Browser-compatible client that mirrors GrpcClient API
4
+ * Specifically designed for Rails ActionCable WebSocket protocol
5
+ */
6
+ import { serializeStack, deserializeStack } from './serializer.js';
7
+ import { RemoteRuntimeError } from './errors.js';
8
+ /**
9
+ * ActionCable client for executing words in remote Forthic runtimes
10
+ * Mirrors the GrpcClient API for compatibility
11
+ * Uses Rails ActionCable WebSocket protocol
12
+ */
13
+ export class ActionCableClient {
14
+ ws;
15
+ config;
16
+ pendingRequests = new Map();
17
+ messageId = 0;
18
+ connected = false;
19
+ connectionPromise;
20
+ constructor(config) {
21
+ this.config = {
22
+ url: config.url,
23
+ timezone: config.timezone || 'UTC',
24
+ reconnect: config.reconnect ?? true,
25
+ reconnectDelay: config.reconnectDelay || 3000,
26
+ channel: config.channel || 'ForthicRuntimeChannel',
27
+ };
28
+ this.connect();
29
+ }
30
+ /**
31
+ * Connect to the WebSocket server
32
+ */
33
+ connect() {
34
+ if (this.connectionPromise) {
35
+ return this.connectionPromise;
36
+ }
37
+ this.connectionPromise = new Promise((resolve, reject) => {
38
+ try {
39
+ this.ws = new WebSocket(this.config.url);
40
+ this.ws.onopen = () => {
41
+ this.connected = true;
42
+ // Subscribe to ActionCable channel
43
+ const subscribeMessage = {
44
+ command: 'subscribe',
45
+ identifier: JSON.stringify({
46
+ channel: this.config.channel,
47
+ timezone: this.config.timezone,
48
+ }),
49
+ };
50
+ this.ws.send(JSON.stringify(subscribeMessage));
51
+ resolve();
52
+ };
53
+ this.ws.onmessage = (event) => {
54
+ this.handleMessage(event);
55
+ };
56
+ this.ws.onerror = (error) => {
57
+ console.error('WebSocket error:', error);
58
+ reject(new Error('WebSocket connection error'));
59
+ };
60
+ this.ws.onclose = () => {
61
+ this.connected = false;
62
+ this.connectionPromise = undefined;
63
+ // Reject all pending requests
64
+ for (const [id, pending] of this.pendingRequests.entries()) {
65
+ pending.reject(new Error('WebSocket connection closed'));
66
+ }
67
+ this.pendingRequests.clear();
68
+ // Attempt reconnect if enabled
69
+ if (this.config.reconnect) {
70
+ setTimeout(() => this.connect(), this.config.reconnectDelay);
71
+ }
72
+ };
73
+ }
74
+ catch (error) {
75
+ reject(error);
76
+ }
77
+ });
78
+ return this.connectionPromise;
79
+ }
80
+ /**
81
+ * Handle incoming WebSocket messages
82
+ */
83
+ handleMessage(event) {
84
+ try {
85
+ const data = JSON.parse(event.data);
86
+ // Handle ActionCable control messages
87
+ if (data.type === 'welcome' || data.type === 'ping' || data.type === 'confirm_subscription') {
88
+ return;
89
+ }
90
+ // Extract the actual message from ActionCable envelope
91
+ const message = data.message || data;
92
+ if (!message.id) {
93
+ console.warn('Received message without ID:', message);
94
+ return;
95
+ }
96
+ // Handle streaming progress updates
97
+ if (message.type === 'streaming_progress') {
98
+ const pending = this.pendingRequests.get(message.id);
99
+ if (pending?.onProgress) {
100
+ pending.onProgress(message.progress);
101
+ }
102
+ return;
103
+ }
104
+ // Handle final responses
105
+ const pending = this.pendingRequests.get(message.id);
106
+ if (!pending) {
107
+ console.warn('Received response for unknown request:', message.id);
108
+ return;
109
+ }
110
+ if (message.error) {
111
+ pending.reject(new RemoteRuntimeError(message.error));
112
+ }
113
+ else {
114
+ pending.resolve(message.result);
115
+ }
116
+ this.pendingRequests.delete(message.id);
117
+ }
118
+ catch (error) {
119
+ console.error('Error handling WebSocket message:', error);
120
+ }
121
+ }
122
+ /**
123
+ * Generate next message ID
124
+ */
125
+ nextMessageId() {
126
+ return `msg-${++this.messageId}-${Date.now()}`;
127
+ }
128
+ /**
129
+ * Send a request and wait for response
130
+ * @template T The expected result type (the value of the `result` field)
131
+ */
132
+ async sendRequest(message) {
133
+ await this.ensureConnected();
134
+ return new Promise((resolve, reject) => {
135
+ this.pendingRequests.set(message.id, { resolve, reject });
136
+ // Wrap message in ActionCable format
137
+ const actionCableMessage = {
138
+ command: 'message',
139
+ identifier: JSON.stringify({
140
+ channel: this.config.channel,
141
+ }),
142
+ data: JSON.stringify(message),
143
+ };
144
+ this.ws.send(JSON.stringify(actionCableMessage));
145
+ });
146
+ }
147
+ /**
148
+ * Send a streaming request with progress callbacks
149
+ * @template T The expected result type (the value of the `result` field)
150
+ */
151
+ async sendStreamingRequest(message, onProgress) {
152
+ await this.ensureConnected();
153
+ return new Promise((resolve, reject) => {
154
+ this.pendingRequests.set(message.id, { resolve, reject, onProgress });
155
+ // Wrap message in ActionCable format
156
+ const actionCableMessage = {
157
+ command: 'message',
158
+ identifier: JSON.stringify({
159
+ channel: this.config.channel,
160
+ }),
161
+ data: JSON.stringify(message),
162
+ };
163
+ this.ws.send(JSON.stringify(actionCableMessage));
164
+ });
165
+ }
166
+ /**
167
+ * Ensure WebSocket is connected
168
+ */
169
+ async ensureConnected() {
170
+ if (!this.connected) {
171
+ await this.connect();
172
+ }
173
+ }
174
+ /**
175
+ * Execute a word in the remote runtime
176
+ * Mirrors GrpcClient.executeWord
177
+ */
178
+ async executeWord(word, stack) {
179
+ const message = {
180
+ type: 'execute_word',
181
+ id: this.nextMessageId(),
182
+ params: {
183
+ word,
184
+ stack: serializeStack(stack),
185
+ },
186
+ };
187
+ const result = await this.sendRequest(message);
188
+ return deserializeStack(result.stack);
189
+ }
190
+ /**
191
+ * Execute a sequence of words (batched execution)
192
+ * Mirrors GrpcClient.executeSequence
193
+ */
194
+ async executeSequence(words, stack) {
195
+ const message = {
196
+ type: 'execute_sequence',
197
+ id: this.nextMessageId(),
198
+ params: {
199
+ words,
200
+ stack: serializeStack(stack),
201
+ },
202
+ };
203
+ const result = await this.sendRequest(message);
204
+ return deserializeStack(result.stack);
205
+ }
206
+ /**
207
+ * List available runtime-specific modules
208
+ * Mirrors GrpcClient.listModules
209
+ */
210
+ async listModules() {
211
+ const message = {
212
+ type: 'list_modules',
213
+ id: this.nextMessageId(),
214
+ };
215
+ const result = await this.sendRequest(message);
216
+ return result.modules || [];
217
+ }
218
+ /**
219
+ * Get detailed information about a specific module
220
+ * Mirrors GrpcClient.getModuleInfo
221
+ */
222
+ async getModuleInfo(moduleName) {
223
+ const message = {
224
+ type: 'get_module_info',
225
+ id: this.nextMessageId(),
226
+ params: {
227
+ module_name: moduleName,
228
+ },
229
+ };
230
+ return await this.sendRequest(message);
231
+ }
232
+ /**
233
+ * Execute code with streaming progress updates (NEW capability)
234
+ */
235
+ async streamingExecute(code, stack, onProgress) {
236
+ const message = {
237
+ type: 'streaming_execute',
238
+ id: this.nextMessageId(),
239
+ params: {
240
+ code,
241
+ stack: serializeStack(stack),
242
+ },
243
+ };
244
+ const result = await this.sendStreamingRequest(message, onProgress);
245
+ return deserializeStack(result.stack);
246
+ }
247
+ /**
248
+ * Close the WebSocket connection
249
+ */
250
+ close() {
251
+ if (this.ws) {
252
+ this.config.reconnect = false; // Disable auto-reconnect
253
+ this.ws.close();
254
+ this.ws = undefined;
255
+ this.connected = false;
256
+ }
257
+ }
258
+ /**
259
+ * Check if the client is connected
260
+ */
261
+ isConnected() {
262
+ return this.connected;
263
+ }
264
+ }
265
+ //# sourceMappingURL=action_cable_client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action_cable_client.js","sourceRoot":"","sources":["../../../src/websocket/action_cable_client.ts"],"names":[],"mappings":"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"}