@resonatehq/sdk 0.9.6 → 0.10.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.
Files changed (234) hide show
  1. package/README.md +84 -12
  2. package/dist/clock.d.ts.map +1 -0
  3. package/dist/clock.js +12 -0
  4. package/dist/clock.js.map +1 -0
  5. package/dist/codec.d.ts +11 -0
  6. package/dist/codec.d.ts.map +1 -0
  7. package/dist/codec.js +115 -0
  8. package/dist/codec.js.map +1 -0
  9. package/dist/computation.d.ts +40 -0
  10. package/dist/computation.d.ts.map +1 -0
  11. package/dist/computation.js +152 -0
  12. package/dist/computation.js.map +1 -0
  13. package/dist/{src/context.d.ts → context.d.ts} +65 -40
  14. package/dist/context.d.ts.map +1 -0
  15. package/dist/{src/context.js → context.js} +131 -153
  16. package/dist/context.js.map +1 -0
  17. package/dist/core.d.ts +45 -0
  18. package/dist/core.d.ts.map +1 -0
  19. package/dist/core.js +140 -0
  20. package/dist/core.js.map +1 -0
  21. package/dist/coroutine.d.ts +37 -0
  22. package/dist/coroutine.d.ts.map +1 -0
  23. package/dist/coroutine.js +258 -0
  24. package/dist/coroutine.js.map +1 -0
  25. package/dist/{src/decorator.d.ts → decorator.d.ts} +8 -8
  26. package/dist/decorator.d.ts.map +1 -0
  27. package/dist/decorator.js +149 -0
  28. package/dist/decorator.js.map +1 -0
  29. package/dist/encryptor.d.ts +10 -0
  30. package/dist/encryptor.d.ts.map +1 -0
  31. package/dist/encryptor.js +9 -0
  32. package/dist/encryptor.js.map +1 -0
  33. package/dist/{src/exceptions.d.ts → exceptions.d.ts} +4 -1
  34. package/dist/exceptions.d.ts.map +1 -0
  35. package/dist/{src/exceptions.js → exceptions.js} +11 -11
  36. package/dist/exceptions.js.map +1 -0
  37. package/dist/{src/heartbeat.d.ts → heartbeat.d.ts} +5 -3
  38. package/dist/heartbeat.d.ts.map +1 -0
  39. package/dist/heartbeat.js +50 -0
  40. package/dist/heartbeat.js.map +1 -0
  41. package/dist/index.d.ts +21 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +15 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/logger.d.ts +33 -0
  46. package/dist/logger.d.ts.map +1 -0
  47. package/dist/logger.js +54 -0
  48. package/dist/logger.js.map +1 -0
  49. package/dist/network/http.d.ts +82 -0
  50. package/dist/network/http.d.ts.map +1 -0
  51. package/dist/network/http.js +339 -0
  52. package/dist/network/http.js.map +1 -0
  53. package/dist/network/local.d.ts +179 -0
  54. package/dist/network/local.d.ts.map +1 -0
  55. package/dist/network/local.js +1232 -0
  56. package/dist/network/local.js.map +1 -0
  57. package/dist/network/network.d.ts +16 -0
  58. package/dist/network/network.d.ts.map +1 -0
  59. package/dist/network/network.js +2 -0
  60. package/dist/network/network.js.map +1 -0
  61. package/dist/network/types.d.ts +1279 -0
  62. package/dist/network/types.d.ts.map +1 -0
  63. package/dist/network/types.js +919 -0
  64. package/dist/network/types.js.map +1 -0
  65. package/dist/{src/options.d.ts → options.d.ts} +10 -4
  66. package/dist/options.d.ts.map +1 -0
  67. package/dist/options.js +32 -0
  68. package/dist/options.js.map +1 -0
  69. package/dist/promises.d.ts +41 -0
  70. package/dist/promises.d.ts.map +1 -0
  71. package/dist/promises.js +113 -0
  72. package/dist/promises.js.map +1 -0
  73. package/dist/{src/registry.d.ts → registry.d.ts} +1 -1
  74. package/dist/registry.d.ts.map +1 -0
  75. package/dist/{src/registry.js → registry.js} +6 -13
  76. package/dist/registry.js.map +1 -0
  77. package/dist/resonate.d.ts +168 -0
  78. package/dist/resonate.d.ts.map +1 -0
  79. package/dist/resonate.js +488 -0
  80. package/dist/resonate.js.map +1 -0
  81. package/dist/retries.d.ts.map +1 -0
  82. package/dist/{src/retries.js → retries.js} +4 -11
  83. package/dist/retries.js.map +1 -0
  84. package/dist/schedules.d.ts +22 -0
  85. package/dist/schedules.d.ts.map +1 -0
  86. package/dist/schedules.js +65 -0
  87. package/dist/schedules.js.map +1 -0
  88. package/dist/trace.d.ts +79 -0
  89. package/dist/trace.d.ts.map +1 -0
  90. package/dist/trace.js +224 -0
  91. package/dist/trace.js.map +1 -0
  92. package/dist/types.d.ts +21 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +2 -0
  95. package/dist/types.js.map +1 -0
  96. package/dist/{src/util.d.ts → util.d.ts} +10 -6
  97. package/dist/util.d.ts.map +1 -0
  98. package/dist/util.js +156 -0
  99. package/dist/util.js.map +1 -0
  100. package/package.json +18 -10
  101. package/dist/dev/network.d.ts +0 -34
  102. package/dist/dev/network.d.ts.map +0 -1
  103. package/dist/dev/network.js +0 -115
  104. package/dist/dev/network.js.map +0 -1
  105. package/dist/dev/server.d.ts +0 -89
  106. package/dist/dev/server.d.ts.map +0 -1
  107. package/dist/dev/server.js +0 -890
  108. package/dist/dev/server.js.map +0 -1
  109. package/dist/sim/example-1.d.ts +0 -2
  110. package/dist/sim/example-1.d.ts.map +0 -1
  111. package/dist/sim/example-1.js +0 -95
  112. package/dist/sim/example-1.js.map +0 -1
  113. package/dist/sim/example-2.d.ts +0 -2
  114. package/dist/sim/example-2.d.ts.map +0 -1
  115. package/dist/sim/example-2.js +0 -97
  116. package/dist/sim/example-2.js.map +0 -1
  117. package/dist/sim/example-3.d.ts +0 -2
  118. package/dist/sim/example-3.d.ts.map +0 -1
  119. package/dist/sim/example-3.js +0 -97
  120. package/dist/sim/example-3.js.map +0 -1
  121. package/dist/sim/main.d.ts +0 -14
  122. package/dist/sim/main.d.ts.map +0 -1
  123. package/dist/sim/main.js +0 -207
  124. package/dist/sim/main.js.map +0 -1
  125. package/dist/sim/src/server.d.ts +0 -15
  126. package/dist/sim/src/server.d.ts.map +0 -1
  127. package/dist/sim/src/server.js +0 -85
  128. package/dist/sim/src/server.js.map +0 -1
  129. package/dist/sim/src/simulator.d.ts +0 -65
  130. package/dist/sim/src/simulator.d.ts.map +0 -1
  131. package/dist/sim/src/simulator.js +0 -236
  132. package/dist/sim/src/simulator.js.map +0 -1
  133. package/dist/sim/src/worker.d.ts +0 -23
  134. package/dist/sim/src/worker.d.ts.map +0 -1
  135. package/dist/sim/src/worker.js +0 -217
  136. package/dist/sim/src/worker.js.map +0 -1
  137. package/dist/src/clock.d.ts.map +0 -1
  138. package/dist/src/clock.js +0 -17
  139. package/dist/src/clock.js.map +0 -1
  140. package/dist/src/computation.d.ts +0 -49
  141. package/dist/src/computation.d.ts.map +0 -1
  142. package/dist/src/computation.js +0 -314
  143. package/dist/src/computation.js.map +0 -1
  144. package/dist/src/context.d.ts.map +0 -1
  145. package/dist/src/context.js.map +0 -1
  146. package/dist/src/core.d.ts +0 -12
  147. package/dist/src/core.d.ts.map +0 -1
  148. package/dist/src/core.js +0 -28
  149. package/dist/src/core.js.map +0 -1
  150. package/dist/src/coroutine.d.ts +0 -42
  151. package/dist/src/coroutine.d.ts.map +0 -1
  152. package/dist/src/coroutine.js +0 -364
  153. package/dist/src/coroutine.js.map +0 -1
  154. package/dist/src/decorator.d.ts.map +0 -1
  155. package/dist/src/decorator.js +0 -220
  156. package/dist/src/decorator.js.map +0 -1
  157. package/dist/src/encoder.d.ts +0 -12
  158. package/dist/src/encoder.d.ts.map +0 -1
  159. package/dist/src/encoder.js +0 -101
  160. package/dist/src/encoder.js.map +0 -1
  161. package/dist/src/encryptor.d.ts +0 -10
  162. package/dist/src/encryptor.d.ts.map +0 -1
  163. package/dist/src/encryptor.js +0 -13
  164. package/dist/src/encryptor.js.map +0 -1
  165. package/dist/src/exceptions.d.ts.map +0 -1
  166. package/dist/src/exceptions.js.map +0 -1
  167. package/dist/src/handler.d.ts +0 -49
  168. package/dist/src/handler.d.ts.map +0 -1
  169. package/dist/src/handler.js +0 -316
  170. package/dist/src/handler.js.map +0 -1
  171. package/dist/src/heartbeat.d.ts.map +0 -1
  172. package/dist/src/heartbeat.js +0 -87
  173. package/dist/src/heartbeat.js.map +0 -1
  174. package/dist/src/index.d.ts +0 -15
  175. package/dist/src/index.d.ts.map +0 -1
  176. package/dist/src/index.js +0 -61
  177. package/dist/src/index.js.map +0 -1
  178. package/dist/src/network/network.d.ts +0 -254
  179. package/dist/src/network/network.d.ts.map +0 -1
  180. package/dist/src/network/network.js +0 -4
  181. package/dist/src/network/network.js.map +0 -1
  182. package/dist/src/network/remote.d.ts +0 -85
  183. package/dist/src/network/remote.d.ts.map +0 -1
  184. package/dist/src/network/remote.js +0 -523
  185. package/dist/src/network/remote.js.map +0 -1
  186. package/dist/src/nursery.d.ts +0 -19
  187. package/dist/src/nursery.d.ts.map +0 -1
  188. package/dist/src/nursery.js +0 -102
  189. package/dist/src/nursery.js.map +0 -1
  190. package/dist/src/options.d.ts.map +0 -1
  191. package/dist/src/options.js +0 -70
  192. package/dist/src/options.js.map +0 -1
  193. package/dist/src/processor/processor.d.ts +0 -12
  194. package/dist/src/processor/processor.d.ts.map +0 -1
  195. package/dist/src/processor/processor.js +0 -43
  196. package/dist/src/processor/processor.js.map +0 -1
  197. package/dist/src/promises.d.ts +0 -54
  198. package/dist/src/promises.d.ts.map +0 -1
  199. package/dist/src/promises.js +0 -169
  200. package/dist/src/promises.js.map +0 -1
  201. package/dist/src/registry.d.ts.map +0 -1
  202. package/dist/src/registry.js.map +0 -1
  203. package/dist/src/resonate-inner.d.ts +0 -60
  204. package/dist/src/resonate-inner.d.ts.map +0 -1
  205. package/dist/src/resonate-inner.js +0 -97
  206. package/dist/src/resonate-inner.js.map +0 -1
  207. package/dist/src/resonate.d.ts +0 -341
  208. package/dist/src/resonate.d.ts.map +0 -1
  209. package/dist/src/resonate.js +0 -591
  210. package/dist/src/resonate.js.map +0 -1
  211. package/dist/src/retries.d.ts.map +0 -1
  212. package/dist/src/retries.js.map +0 -1
  213. package/dist/src/schedules.d.ts +0 -19
  214. package/dist/src/schedules.d.ts.map +0 -1
  215. package/dist/src/schedules.js +0 -85
  216. package/dist/src/schedules.js.map +0 -1
  217. package/dist/src/tasks.d.ts +0 -9
  218. package/dist/src/tasks.d.ts.map +0 -1
  219. package/dist/src/tasks.js +0 -61
  220. package/dist/src/tasks.js.map +0 -1
  221. package/dist/src/tracer.d.ts +0 -23
  222. package/dist/src/tracer.d.ts.map +0 -1
  223. package/dist/src/tracer.js +0 -25
  224. package/dist/src/tracer.js.map +0 -1
  225. package/dist/src/types.d.ts +0 -28
  226. package/dist/src/types.d.ts.map +0 -1
  227. package/dist/src/types.js +0 -11
  228. package/dist/src/types.js.map +0 -1
  229. package/dist/src/util.d.ts.map +0 -1
  230. package/dist/src/util.js +0 -120
  231. package/dist/src/util.js.map +0 -1
  232. package/dist/tsconfig.build.tsbuildinfo +0 -1
  233. /package/dist/{src/clock.d.ts → clock.d.ts} +0 -0
  234. /package/dist/{src/retries.d.ts → retries.d.ts} +0 -0
@@ -1,890 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.Server = void 0;
40
- const cron_parser_1 = require("cron-parser");
41
- const exceptions_1 = __importDefault(require("../src/exceptions"));
42
- const util = __importStar(require("../src/util"));
43
- class TagRouter {
44
- tag;
45
- constructor(tag = "resonate:invoke") {
46
- this.tag = tag;
47
- }
48
- route(promise) {
49
- return promise.tags?.[this.tag];
50
- }
51
- }
52
- class Server {
53
- promises;
54
- tasks;
55
- schedules;
56
- routers;
57
- targets;
58
- constructor() {
59
- this.promises = new Map();
60
- this.tasks = new Map();
61
- this.schedules = new Map();
62
- this.routers = new Array(new TagRouter());
63
- this.targets = { default: "local://any@default" };
64
- }
65
- next(time) {
66
- let timeout;
67
- // Check promises
68
- for (const promise of this.promises.values()) {
69
- if (promise.state === "pending") {
70
- timeout = Math.min(promise.timeout, timeout ?? promise.timeout);
71
- }
72
- }
73
- // Check schedules
74
- for (const schedule of this.schedules.values()) {
75
- util.assertDefined(schedule.nextRunTime);
76
- timeout = Math.min(schedule.nextRunTime, timeout ?? schedule.nextRunTime);
77
- }
78
- // Check tasks
79
- for (const task of this.tasks.values()) {
80
- if (["init", "claimed", "enqueued"].includes(task.state)) {
81
- timeout = Math.min(task.expiry, timeout ?? task.expiry);
82
- }
83
- }
84
- // Convert to delay relative to `time`, clamped to signed 32-bit range
85
- return timeout !== undefined ? Math.min(Math.max(0, timeout - time), 2147483647) : timeout;
86
- }
87
- step(time) {
88
- for (const schedule of this.schedules.values()) {
89
- util.assertDefined(schedule.nextRunTime);
90
- if (time < schedule.nextRunTime) {
91
- continue;
92
- }
93
- try {
94
- this.createPromise({
95
- id: schedule.promiseId.replace("{{.timestamp}}", time.toString()),
96
- timeout: time + schedule.promiseTimeout,
97
- param: schedule.promiseParam,
98
- tags: schedule.promiseTags,
99
- strict: false,
100
- time,
101
- });
102
- }
103
- catch { }
104
- const { applied } = this.transitionSchedule({ id: schedule.id, to: "created", updating: true, time });
105
- util.assert(applied, `step(): failed to transition schedule '${schedule.id}' to 'created' state`);
106
- }
107
- // Reject timed-out promises
108
- for (const promise of this.promises.values()) {
109
- if (promise.state === "pending" && time >= promise.timeout) {
110
- const { applied } = this.transitionPromise({ id: promise.id, to: "rejected_timedout", time });
111
- util.assert(applied, `step(): promise '${promise.id}' expected to be timed out but transition did not apply`);
112
- }
113
- }
114
- // Transition expired tasks back to init
115
- for (const task of this.tasks.values()) {
116
- if (["enqueued", "claimed"].includes(task.state)) {
117
- util.assertDefined(task.expiry);
118
- if (time >= task.expiry) {
119
- const { applied } = this.transitionTask({ id: task.id, to: "init", force: true, time });
120
- util.assert(applied, `step(): failed to force-reinit expired task '${task.id}'`);
121
- }
122
- }
123
- }
124
- const inFlightRootPromiseIds = new Set();
125
- for (const task of this.tasks.values()) {
126
- if (["enqueued", "claimed"].includes(task.state)) {
127
- inFlightRootPromiseIds.add(task.rootPromiseId);
128
- }
129
- }
130
- const msgs = [];
131
- for (const task of this.tasks.values()) {
132
- if (task.state !== "init" || task.expiry > time || inFlightRootPromiseIds.has(task.rootPromiseId)) {
133
- continue;
134
- }
135
- let msg;
136
- if (task.type === "invoke") {
137
- msg = {
138
- msg: {
139
- type: "invoke",
140
- task: {
141
- ...task,
142
- timeout: this.getPromise({ id: task.rootPromiseId }).timeout,
143
- },
144
- headers: {},
145
- },
146
- recv: task.recv,
147
- };
148
- }
149
- else if (task.type === "resume") {
150
- msg = {
151
- msg: {
152
- type: "resume",
153
- task: {
154
- ...task,
155
- timeout: this.getPromise({ id: task.rootPromiseId }).timeout,
156
- },
157
- headers: {},
158
- },
159
- recv: task.recv,
160
- };
161
- }
162
- else {
163
- util.assert(task.type === "notify", `step(): unexpected task type '${task.type}' for notify message`);
164
- msg = {
165
- msg: {
166
- type: "notify",
167
- promise: this.getPromise({ id: task.rootPromiseId }),
168
- headers: {},
169
- },
170
- recv: task.recv,
171
- };
172
- }
173
- msgs.push(msg);
174
- if (task.type === "notify") {
175
- const { applied } = this.transitionTask({ id: task.id, to: "completed", time });
176
- util.assert(applied, `step(): failed to complete notify task '${task.id}'`);
177
- }
178
- else {
179
- const { applied } = this.transitionTask({ id: task.id, to: "enqueued", time });
180
- util.assert(applied, `step(): failed to enqueue task '${task.id}' after invoking/resuming`);
181
- }
182
- inFlightRootPromiseIds.add(task.rootPromiseId);
183
- }
184
- return msgs;
185
- }
186
- process(requ, time) {
187
- switch (requ.kind) {
188
- case "createPromise": {
189
- return {
190
- kind: requ.kind,
191
- promise: this.createPromise({
192
- ...requ,
193
- time,
194
- }),
195
- };
196
- }
197
- case "createPromiseAndTask": {
198
- const { promise, task } = this.createPromiseAndTask({
199
- id: requ.promise.id,
200
- timeout: requ.promise.timeout,
201
- processId: requ.task.processId,
202
- ttl: requ.task.ttl,
203
- param: requ.promise.param,
204
- tags: requ.promise.tags,
205
- iKey: requ.iKey,
206
- strict: requ.strict,
207
- time,
208
- });
209
- return {
210
- kind: requ.kind,
211
- promise: promise,
212
- task: task,
213
- };
214
- }
215
- case "readPromise": {
216
- return {
217
- kind: requ.kind,
218
- promise: this.readPromise({ ...requ }),
219
- };
220
- }
221
- case "completePromise": {
222
- return {
223
- kind: requ.kind,
224
- promise: this.completePromise({
225
- ...requ,
226
- time,
227
- }),
228
- };
229
- }
230
- case "createCallback": {
231
- return {
232
- kind: requ.kind,
233
- ...this.createCallback({
234
- ...requ,
235
- time,
236
- }),
237
- };
238
- }
239
- case "createSubscription": {
240
- return {
241
- kind: requ.kind,
242
- ...this.createSubscription({ ...requ, time }),
243
- };
244
- }
245
- case "createSchedule": {
246
- return {
247
- kind: requ.kind,
248
- schedule: this.createSchedule({
249
- id: requ.id,
250
- cron: requ.cron,
251
- promiseId: requ.promiseId,
252
- promiseTimeout: requ.promiseTimeout,
253
- iKey: requ.iKey,
254
- description: requ.description,
255
- tags: requ.tags,
256
- promiseParam: requ.promiseParam,
257
- promiseTags: requ.promiseTags,
258
- time,
259
- }),
260
- };
261
- }
262
- case "readSchedule": {
263
- return { kind: requ.kind, schedule: this.readSchedule({ ...requ }) };
264
- }
265
- case "deleteSchedule": {
266
- this.deleteSchedule({ ...requ, time });
267
- return { kind: requ.kind };
268
- }
269
- case "claimTask": {
270
- return {
271
- kind: "claimTask",
272
- message: this.claimTask({
273
- ...requ,
274
- time,
275
- }),
276
- };
277
- }
278
- case "completeTask": {
279
- return {
280
- kind: "completeTask",
281
- task: this.completeTask({ ...requ, time }),
282
- };
283
- }
284
- case "heartbeatTasks": {
285
- return {
286
- kind: "heartbeatTasks",
287
- tasksAffected: this.heartbeatTasks({ ...requ, time }),
288
- };
289
- }
290
- case "dropTask": {
291
- this.dropTask({ ...requ, time });
292
- return { kind: "dropTask" };
293
- }
294
- case "searchPromises": {
295
- return { kind: "searchPromises", promises: this.searchPromises({ ...requ }) };
296
- }
297
- case "searchSchedules": {
298
- return { kind: "searchSchedules", schedules: this.searchSchedules({ ...requ }) };
299
- }
300
- }
301
- }
302
- createPromise({ id, timeout, param, tags, iKey, strict, time, }) {
303
- return this._createPromise({
304
- id,
305
- timeout,
306
- param,
307
- tags,
308
- iKey,
309
- strict,
310
- time,
311
- }).promise;
312
- }
313
- createPromiseAndTask({ id, timeout, processId, ttl, param, tags, iKey, strict, time, }) {
314
- const { promise, task } = this._createPromise({
315
- id,
316
- timeout,
317
- processId,
318
- ttl,
319
- param,
320
- tags,
321
- iKey,
322
- strict,
323
- time,
324
- });
325
- if (task === undefined) {
326
- return { promise };
327
- }
328
- return { promise, task: { ...task, timeout: promise.timeout } };
329
- }
330
- _createPromise({ id, timeout, param, tags, iKey, strict, processId, ttl, time, }) {
331
- const { promise, task, applied } = this.transitionPromise({
332
- id,
333
- to: "pending",
334
- strict,
335
- timeout,
336
- iKey,
337
- value: param,
338
- tags,
339
- time,
340
- });
341
- util.assert(!applied || ["pending", "rejected_timedout"].includes(promise.state), `createPromise: unexpected promise state '${promise.state}' after transition to 'pending' for promise '${id}'`);
342
- if (applied && task !== undefined && processId !== undefined) {
343
- const { task: newTask, applied: appliedTask } = this.transitionTask({
344
- id: task.id,
345
- to: "claimed",
346
- counter: 1,
347
- processId,
348
- ttl,
349
- time,
350
- });
351
- util.assert(appliedTask, `createPromise: failed to claim task '${task.id}' for subsequent processing`);
352
- return { promise: promise, task: newTask };
353
- }
354
- return { promise, task };
355
- }
356
- readPromise({ id }) {
357
- return this.getPromise({ id });
358
- }
359
- completePromise({ id, state, value, iKey, strict, time, }) {
360
- const { promise, applied } = this.transitionPromise({
361
- id,
362
- to: state,
363
- strict,
364
- iKey,
365
- value,
366
- time,
367
- });
368
- util.assert(!applied || [state, "rejected_timedout"].includes(promise.state), `completePromise: after transition to '${state}', promise '${id}' is in unexpected state '${promise.state}'`);
369
- return promise;
370
- }
371
- createSubscription({ id, promiseId, timeout, recv, time, }) {
372
- {
373
- const record = this.promises.get(promiseId);
374
- if (!record) {
375
- throw exceptions_1.default.SERVER_ERROR("Promise not found");
376
- }
377
- const cbId = `__notify:${promiseId}:${id}`;
378
- if (record.state !== "pending" || record.callbacks?.has(cbId)) {
379
- return { promise: record, callback: undefined };
380
- }
381
- const callback = {
382
- id: cbId,
383
- type: "notify",
384
- promiseId: promiseId,
385
- rootPromiseId: promiseId,
386
- recv,
387
- timeout,
388
- createdOn: time,
389
- };
390
- if (!record.callbacks) {
391
- record.callbacks = new Map();
392
- }
393
- // register and return
394
- record.callbacks.set(cbId, callback);
395
- return {
396
- promise: record,
397
- callback: callback,
398
- };
399
- }
400
- }
401
- createCallback({ promiseId, rootPromiseId, timeout, recv, time, }) {
402
- const record = this.promises.get(promiseId);
403
- if (!record) {
404
- throw exceptions_1.default.SERVER_ERROR("Promise not found");
405
- }
406
- if (record.state !== "pending" || record.callbacks?.has(promiseId)) {
407
- return { promise: record, callback: undefined };
408
- }
409
- const callback = {
410
- id: `__resume:${rootPromiseId}:${promiseId}`,
411
- type: "resume",
412
- promiseId,
413
- rootPromiseId,
414
- recv,
415
- timeout,
416
- createdOn: time,
417
- };
418
- if (!record.callbacks) {
419
- record.callbacks = new Map();
420
- }
421
- record.callbacks.set(callback.id, callback);
422
- return { promise: record, callback: callback };
423
- }
424
- claimTask({ id, counter, processId, ttl, time, }) {
425
- const { task, applied } = this.transitionTask({
426
- id,
427
- to: "claimed",
428
- counter,
429
- processId,
430
- ttl,
431
- time,
432
- });
433
- util.assert(applied, `claimTask: failed to claim task '${id}' with counter ${counter} using processId '${processId}'`);
434
- switch (task.type) {
435
- case "invoke": {
436
- const promise = this.getPromise({ id: task.rootPromiseId });
437
- return {
438
- kind: task.type,
439
- promises: {
440
- root: { id: promise.id, data: promise },
441
- },
442
- };
443
- }
444
- case "resume": {
445
- return {
446
- kind: task.type,
447
- promises: {
448
- root: {
449
- id: task.rootPromiseId,
450
- data: this.getPromise({ id: task.rootPromiseId }),
451
- },
452
- leaf: {
453
- id: task.leafPromiseId,
454
- data: this.getPromise({ id: task.leafPromiseId }),
455
- },
456
- },
457
- };
458
- }
459
- case "notify":
460
- throw exceptions_1.default.SERVER_ERROR(`Unexpected task type '${task.type}' notify`);
461
- }
462
- }
463
- completeTask({ id, counter, time }) {
464
- const { task } = this.transitionTask({ id, to: "completed", counter, time });
465
- return task;
466
- }
467
- dropTask({ id, counter, time }) {
468
- const { applied } = this.transitionTask({ id, to: "init", counter, time });
469
- util.assert(applied);
470
- return;
471
- }
472
- searchPromises({ id }) {
473
- return Array.from(this.promises.values());
474
- }
475
- searchSchedules({ id }) {
476
- return Array.from(this.schedules.values());
477
- }
478
- heartbeatTasks({ processId, time }) {
479
- let affectedTasks = 0;
480
- for (const task of this.tasks.values()) {
481
- if (task.state !== "claimed" || task.processId !== processId) {
482
- continue;
483
- }
484
- const { applied } = this.transitionTask({ id: task.id, to: "claimed", force: true, time });
485
- util.assert(applied, `heartbeatTasks: failed to refresh heartbeat for task '${task.id}' owned by process '${processId}'`);
486
- affectedTasks += 1;
487
- }
488
- return affectedTasks;
489
- }
490
- createSchedule({ id, cron, promiseId, promiseTimeout, iKey, description, tags, promiseParam, promiseTags, time, }) {
491
- return this.transitionSchedule({
492
- id,
493
- to: "created",
494
- cron,
495
- promiseId,
496
- promiseTimeout,
497
- iKey,
498
- description,
499
- tags,
500
- promiseParam,
501
- promiseTags,
502
- time,
503
- }).schedule;
504
- }
505
- readSchedule({ id }) {
506
- const schedule = this.schedules.get(id);
507
- if (schedule === undefined) {
508
- throw exceptions_1.default.SERVER_ERROR("Schedule not found");
509
- }
510
- return schedule;
511
- }
512
- deleteSchedule({ id, time }) {
513
- const { applied } = this.transitionSchedule({ id, to: "deleted", time });
514
- util.assert(applied, `deleteSchedule: failed to delete schedule '${id}'`);
515
- }
516
- getPromise({ id }) {
517
- const record = this.promises.get(id);
518
- if (!record) {
519
- throw exceptions_1.default.SERVER_ERROR("Promise not found");
520
- }
521
- return record;
522
- }
523
- transitionPromise({ id, to, strict, timeout, iKey, value, tags, time, }) {
524
- const { promise, applied } = this._transitionPromise({
525
- id,
526
- to,
527
- strict,
528
- timeout,
529
- iKey,
530
- value,
531
- tags,
532
- time,
533
- });
534
- // Initialize invocation tasks on pending
535
- if (applied && promise.state === "pending") {
536
- for (const router of this.routers) {
537
- const recv = router.route(promise);
538
- if (recv !== undefined) {
539
- const { task, applied } = this.transitionTask({
540
- id: `__invoke:${id}`,
541
- to: "init",
542
- type: "invoke",
543
- recv: this.targets[recv] ?? recv,
544
- rootPromiseId: promise.id,
545
- leafPromiseId: promise.id,
546
- timeout: promise.timeout,
547
- time,
548
- });
549
- util.assert(applied, `transitionPromise: failed to init invoke task for promise '${id}' on route '${recv}'`);
550
- return { promise, task, applied };
551
- }
552
- }
553
- }
554
- // Complete any tasks and schedule callbacks after resolution
555
- if (applied && ["resolved", "rejected", "rejected_canceled", "rejected_timedout"].includes(promise.state)) {
556
- // Mark existing tasks as completed
557
- for (const task of this.tasks.values()) {
558
- if (task.rootPromiseId === id && ["init", "enqueued", "claimed"].includes(task.state)) {
559
- const { applied } = this.transitionTask({
560
- id: task.id,
561
- to: "completed",
562
- force: true,
563
- time,
564
- });
565
- util.assert(applied, `transitionPromise: failed to complete task '${task.id}' for promise '${id}'`);
566
- }
567
- }
568
- // Initialize callback tasks
569
- if (promise.callbacks) {
570
- for (const callback of promise.callbacks.values()) {
571
- const { applied } = this.transitionTask({
572
- ...callback,
573
- to: "init",
574
- leafPromiseId: callback.promiseId,
575
- time,
576
- });
577
- util.assert(applied, `transitionPromise: failed to init callback task '${callback.id}' for promise '${id}'`);
578
- }
579
- promise.callbacks.clear();
580
- }
581
- }
582
- return { promise, applied };
583
- }
584
- _transitionPromise({ id, to, strict, timeout, iKey, value, tags, time, }) {
585
- let record = this.promises.get(id);
586
- // Create new promise
587
- if (record === undefined && to === "pending") {
588
- util.assertDefined(timeout);
589
- record = {
590
- id,
591
- state: to,
592
- timeout,
593
- iKeyForCreate: iKey,
594
- param: value,
595
- value: undefined,
596
- tags: tags ?? {},
597
- createdOn: time,
598
- };
599
- this.promises.set(id, record);
600
- return { promise: record, applied: true };
601
- }
602
- // Cannot complete non-existent promise
603
- if (record === undefined && ["resolved", "rejected", "rejected_canceled"].includes(to)) {
604
- throw exceptions_1.default.SERVER_ERROR("Promise not found");
605
- }
606
- // No-op re-create pending if before timeout and same iKey
607
- if (record?.state === "pending" &&
608
- to === "pending" &&
609
- time < record.timeout &&
610
- ikeyMatch(record.iKeyForCreate, iKey)) {
611
- return { promise: record, applied: false };
612
- }
613
- // Auto-timeout transition
614
- if (record?.state === "pending" &&
615
- to === "pending" &&
616
- !strict &&
617
- time >= record.timeout &&
618
- ikeyMatch(record.iKeyForCreate, iKey)) {
619
- return this._transitionPromise({ id, to: "rejected_timedout", time });
620
- }
621
- // Resolve or reject before timeout
622
- if (record?.state === "pending" &&
623
- ["resolved", "rejected", "rejected_canceled"].includes(to) &&
624
- time < record.timeout) {
625
- record = {
626
- ...record,
627
- state: to,
628
- iKeyForComplete: iKey,
629
- value: value,
630
- completedOn: time,
631
- };
632
- this.promises.set(id, record);
633
- return { promise: record, applied: true };
634
- }
635
- // Attempt completion after timeout without strict -> treat as timeout
636
- if (record?.state === "pending" &&
637
- ["resolved", "rejected", "rejected_canceled"].includes(to) &&
638
- !strict &&
639
- time >= record.timeout) {
640
- return this._transitionPromise({ id, to: "rejected_timedout", time });
641
- }
642
- // Strict completion after timeout -> error
643
- if (record?.state === "pending" &&
644
- ["resolved", "rejected", "rejected_canceled"].includes(to) &&
645
- strict &&
646
- time >= record.timeout) {
647
- throw exceptions_1.default.SERVER_ERROR("Promise already timedout");
648
- }
649
- // Transition to timed-out
650
- if (record?.state === "pending" && to === "rejected_timedout") {
651
- util.assert(time >= record.timeout, `transitionPromise(rejected_timedout): cannot time out promise '${id}' before its timeout (${record.timeout})`);
652
- record = {
653
- ...record,
654
- state: record.tags?.["resonate:timeout"] === "true" ? "resolved" : to,
655
- };
656
- this.promises.set(id, record);
657
- return { promise: record, applied: true };
658
- }
659
- // No-op re-pending or re-completing without strict and matching iKey
660
- if (record?.state !== undefined &&
661
- ["resolved", "rejected", "rejected_canceled", "rejected_timedout"].includes(record.state) &&
662
- to === "pending" &&
663
- !strict &&
664
- ikeyMatch(record.iKeyForCreate, iKey)) {
665
- return { promise: record, applied: false };
666
- }
667
- if (record !== undefined &&
668
- ["resolved", "rejected", "rejected_canceled"].includes(record.state) &&
669
- ["resolved", "rejected", "rejected_canceled"].includes(to) &&
670
- !strict &&
671
- ikeyMatch(record.iKeyForComplete, iKey)) {
672
- return { promise: record, applied: false };
673
- }
674
- if (record?.state === "rejected_timedout" &&
675
- ["resolved", "rejected", "rejected_canceled"].includes(to) &&
676
- !strict) {
677
- return { promise: record, applied: false };
678
- }
679
- if (record !== undefined &&
680
- ["resolved", "rejected", "rejected_canceled"].includes(record.state) &&
681
- ["resolved", "rejected", "rejected_canceled"].includes(to) &&
682
- strict &&
683
- ikeyMatch(record.iKeyForComplete, iKey) &&
684
- record.state === to) {
685
- return { promise: record, applied: false };
686
- }
687
- // Fallback
688
- throw exceptions_1.default.SERVER_ERROR("Unexpected promise transition");
689
- }
690
- transitionTask({ id, to, type, recv, timeout, rootPromiseId, leafPromiseId, counter, processId, ttl, force, time, }) {
691
- let record = this.tasks.get(id);
692
- if (record === undefined && to === "init") {
693
- util.assertDefined(type);
694
- util.assertDefined(recv);
695
- util.assertDefined(rootPromiseId);
696
- util.assertDefined(leafPromiseId);
697
- util.assertDefined(timeout);
698
- record = {
699
- id,
700
- counter: 1,
701
- timeout,
702
- state: to,
703
- type,
704
- recv,
705
- rootPromiseId,
706
- leafPromiseId,
707
- expiry: 0,
708
- createdOn: time,
709
- };
710
- this.tasks.set(id, record);
711
- return { task: record, applied: true };
712
- }
713
- if (record?.state === "init" && to === "enqueued") {
714
- record = {
715
- ...record,
716
- state: to,
717
- expiry: time + 5000, // wait 5s before transitioning back to init if unclaimed
718
- };
719
- this.tasks.set(id, record);
720
- return { task: record, applied: true };
721
- }
722
- if (record?.state === "init" && to === "claimed" && record.counter === counter) {
723
- util.assertDefined(processId);
724
- util.assertDefined(ttl);
725
- util.assertDefined(counter);
726
- record = {
727
- ...record,
728
- state: to,
729
- processId,
730
- ttl,
731
- expiry: time + ttl,
732
- };
733
- this.tasks.set(id, record);
734
- return { task: record, applied: true };
735
- }
736
- if (record?.state === "enqueued" && to === "claimed" && record.counter === counter) {
737
- util.assertDefined(ttl);
738
- util.assertDefined(counter);
739
- util.assertDefined(processId);
740
- record = {
741
- ...record,
742
- state: to,
743
- processId,
744
- ttl,
745
- expiry: time + ttl,
746
- };
747
- this.tasks.set(id, record);
748
- return { task: record, applied: true };
749
- }
750
- if (record !== undefined &&
751
- ["init", "enqueued"].includes(record.state) &&
752
- record.type === "notify" &&
753
- to === "completed") {
754
- record = {
755
- ...record,
756
- state: to,
757
- completedOn: time,
758
- };
759
- this.tasks.set(id, record);
760
- return { task: record, applied: true };
761
- }
762
- if (record !== undefined && record.state === "claimed" && record.counter === counter && to === "init") {
763
- record = {
764
- ...record,
765
- counter: record.counter + 1,
766
- state: to,
767
- processId: undefined,
768
- ttl: undefined,
769
- expiry: time + 5000, // wait 5s before sending again
770
- };
771
- this.tasks.set(id, record);
772
- return { task: record, applied: true };
773
- }
774
- if (record !== undefined && ["enqueued", "claimed"].includes(record.state) && to === "init") {
775
- util.assertDefined(record.expiry);
776
- record = {
777
- ...record,
778
- counter: record.counter + 1,
779
- state: to,
780
- processId: undefined,
781
- ttl: undefined,
782
- expiry: 0,
783
- };
784
- this.tasks.set(id, record);
785
- return { task: record, applied: true };
786
- }
787
- if (record?.state === "claimed" && to === "claimed" && force) {
788
- util.assertDefined(record.ttl);
789
- record = {
790
- ...record,
791
- expiry: time + record.ttl,
792
- };
793
- this.tasks.set(id, record);
794
- return { task: record, applied: true };
795
- }
796
- if (record?.state === "claimed" &&
797
- to === "completed" &&
798
- record.counter === counter &&
799
- record.expiry !== undefined &&
800
- record.expiry >= time) {
801
- record = {
802
- ...record,
803
- state: to,
804
- completedOn: time,
805
- };
806
- this.tasks.set(id, record);
807
- return { task: record, applied: true };
808
- }
809
- if (record !== undefined &&
810
- ["init", "enqueued", "claimed"].includes(record?.state) &&
811
- to === "completed" &&
812
- force) {
813
- record = {
814
- ...record,
815
- state: to,
816
- completedOn: time,
817
- };
818
- this.tasks.set(id, record);
819
- return { task: record, applied: true };
820
- }
821
- if (record?.state === "completed" && to === "completed") {
822
- return { task: record, applied: false };
823
- }
824
- if (record === undefined) {
825
- throw exceptions_1.default.SERVER_ERROR("Task not found");
826
- }
827
- throw exceptions_1.default.SERVER_ERROR("Task is already claimed, completed, or an invalid counter was provided");
828
- }
829
- transitionSchedule({ id, to, cron, promiseId, promiseTimeout, iKey, description, tags, promiseParam, promiseTags, updating, time, }) {
830
- let record = this.schedules.get(id);
831
- // Create new schedule
832
- if (record === undefined && to === "created") {
833
- util.assertDefined(cron);
834
- util.assertDefined(promiseId);
835
- util.assertDefined(promiseTimeout);
836
- util.assert(promiseTimeout >= 0, "promiseTimeout must be non-negative");
837
- record = {
838
- id,
839
- description,
840
- cron,
841
- tags: tags ?? {},
842
- promiseId,
843
- promiseTimeout,
844
- promiseParam,
845
- promiseTags: promiseTags ?? {},
846
- nextRunTime: cron_parser_1.CronExpressionParser.parse(cron, { currentDate: time }).next().getTime(),
847
- iKey,
848
- createdOn: time,
849
- lastRunTime: 0,
850
- };
851
- this.schedules.set(id, record);
852
- return { schedule: record, applied: true };
853
- }
854
- // No-op if same iKey
855
- if (record !== undefined && to === "created" && ikeyMatch(iKey, record.iKey)) {
856
- return { schedule: record, applied: false };
857
- }
858
- // Update existing schedule
859
- if (record !== undefined && to === "created" && updating) {
860
- const nextRunTime = cron_parser_1.CronExpressionParser.parse(record.cron, { currentDate: time }).next().getTime();
861
- record = {
862
- ...record,
863
- lastRunTime: record.nextRunTime,
864
- nextRunTime: nextRunTime,
865
- };
866
- this.schedules.set(id, record);
867
- return { schedule: record, applied: true };
868
- }
869
- // Schedule exists and not updating
870
- if (record !== undefined && to === "created") {
871
- throw exceptions_1.default.SERVER_ERROR("Schedule already exists");
872
- }
873
- // Delete non-existent
874
- if (record === undefined && to === "deleted") {
875
- throw exceptions_1.default.SERVER_ERROR("Schedule not found");
876
- }
877
- // Delete existing
878
- if (record !== undefined && to === "deleted") {
879
- this.schedules.delete(id);
880
- return { schedule: record, applied: true };
881
- }
882
- // Fallback error
883
- throw exceptions_1.default.SERVER_ERROR("Unexpected schedule transition");
884
- }
885
- }
886
- exports.Server = Server;
887
- function ikeyMatch(left, right) {
888
- return left !== undefined && right !== undefined && left === right;
889
- }
890
- //# sourceMappingURL=server.js.map