@kithinji/orca 1.0.16 → 1.0.18

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 (74) hide show
  1. package/dist/browser/index.iife.js +1041 -249
  2. package/dist/browser/index.iife.js.map +4 -4
  3. package/dist/browser/index.mjs +5080 -893
  4. package/dist/browser/index.mjs.map +4 -4
  5. package/dist/node/index.cjs +1190 -382
  6. package/dist/node/index.cjs.map +4 -4
  7. package/dist/node/index.mjs +1165 -381
  8. package/dist/node/index.mjs.map +4 -4
  9. package/dist/types/browser/dom/dom.d.ts.map +1 -1
  10. package/dist/types/browser/factory.d.ts +7 -0
  11. package/dist/types/browser/factory.d.ts.map +1 -1
  12. package/dist/types/browser/index.d.ts +1 -0
  13. package/dist/types/browser/index.d.ts.map +1 -1
  14. package/dist/types/browser/modules/actor/actor.d.ts +15 -0
  15. package/dist/types/browser/modules/actor/actor.d.ts.map +1 -0
  16. package/dist/types/browser/modules/actor/index.d.ts +2 -0
  17. package/dist/types/browser/modules/actor/index.d.ts.map +1 -0
  18. package/dist/types/browser/modules/index.d.ts +3 -0
  19. package/dist/types/browser/modules/index.d.ts.map +1 -0
  20. package/dist/types/browser/modules/router_module/index.d.ts.map +1 -0
  21. package/dist/types/browser/modules/router_module/module.d.ts.map +1 -0
  22. package/dist/types/browser/modules/router_module/navigate.d.ts +21 -0
  23. package/dist/types/browser/modules/router_module/navigate.d.ts.map +1 -0
  24. package/dist/types/browser/modules/router_module/outlet.d.ts +12 -0
  25. package/dist/types/browser/modules/router_module/outlet.d.ts.map +1 -0
  26. package/dist/types/index.browser.d.ts +1 -0
  27. package/dist/types/index.browser.d.ts.map +1 -1
  28. package/dist/types/index.d.ts +1 -1
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/dist/types/node/factory.d.ts +6 -2
  31. package/dist/types/node/factory.d.ts.map +1 -1
  32. package/dist/types/node/modules/actor/actor.d.ts +13 -0
  33. package/dist/types/node/modules/actor/actor.d.ts.map +1 -0
  34. package/dist/types/node/modules/actor/index.d.ts +2 -0
  35. package/dist/types/node/modules/actor/index.d.ts.map +1 -0
  36. package/dist/types/node/modules/index.d.ts +2 -0
  37. package/dist/types/node/modules/index.d.ts.map +1 -1
  38. package/dist/types/node/modules/router_module/index.d.ts +15 -0
  39. package/dist/types/node/modules/router_module/index.d.ts.map +1 -0
  40. package/dist/types/node/modules/serve_static/serve.d.ts.map +1 -1
  41. package/dist/types/shared/component.d.ts +1 -1
  42. package/dist/types/shared/decorators.d.ts +3 -0
  43. package/dist/types/shared/decorators.d.ts.map +1 -1
  44. package/dist/types/shared/index.d.ts +1 -0
  45. package/dist/types/shared/index.d.ts.map +1 -1
  46. package/dist/types/shared/module_libs/index.d.ts +0 -1
  47. package/dist/types/shared/module_libs/index.d.ts.map +1 -1
  48. package/dist/types/shared/observable/bsubject.d.ts +12 -0
  49. package/dist/types/shared/observable/bsubject.d.ts.map +1 -0
  50. package/dist/types/shared/observable/index.d.ts +2 -0
  51. package/dist/types/shared/observable/index.d.ts.map +1 -1
  52. package/dist/types/shared/observable/observable.d.ts +15 -7
  53. package/dist/types/shared/observable/observable.d.ts.map +1 -1
  54. package/dist/types/shared/observable/subject.d.ts +13 -0
  55. package/dist/types/shared/observable/subject.d.ts.map +1 -0
  56. package/dist/types/shared/providers/actor.d.ts +15 -0
  57. package/dist/types/shared/providers/actor.d.ts.map +1 -0
  58. package/dist/types/shared/providers/index.d.ts +2 -0
  59. package/dist/types/shared/providers/index.d.ts.map +1 -0
  60. package/dist/types/shared/renderers/stream.d.ts.map +1 -1
  61. package/dist/types/shared/signal/signal.d.ts.map +1 -1
  62. package/dist/types/shared/symbols.d.ts +3 -0
  63. package/dist/types/shared/symbols.d.ts.map +1 -1
  64. package/dist/types/shared/types.d.ts +16 -1
  65. package/dist/types/shared/types.d.ts.map +1 -1
  66. package/package.json +3 -1
  67. package/dist/types/shared/module_libs/router_module/index.d.ts.map +0 -1
  68. package/dist/types/shared/module_libs/router_module/module.d.ts.map +0 -1
  69. package/dist/types/shared/module_libs/router_module/navigate.d.ts +0 -17
  70. package/dist/types/shared/module_libs/router_module/navigate.d.ts.map +0 -1
  71. package/dist/types/shared/module_libs/router_module/outlet.d.ts +0 -7
  72. package/dist/types/shared/module_libs/router_module/outlet.d.ts.map +0 -1
  73. /package/dist/types/{shared/module_libs → browser/modules}/router_module/index.d.ts +0 -0
  74. /package/dist/types/{shared/module_libs → browser/modules}/router_module/module.d.ts +0 -0
@@ -28,13 +28,17 @@ var kithinjiorca = (() => {
28
28
  // src/index.browser.ts
29
29
  var index_browser_exports = {};
30
30
  __export(index_browser_exports, {
31
+ Actor: () => Actor,
32
+ ActorModule: () => ActorModule,
31
33
  BOOTSTRAP: () => BOOTSTRAP,
32
34
  BOOTSTRAP_VNODE: () => BOOTSTRAP_VNODE,
35
+ BehaviorSubject: () => BehaviorSubject,
33
36
  Body: () => Body,
34
37
  BrowserFactory: () => BrowserFactory,
35
38
  COMPONENT: () => COMPONENT,
36
39
  COMPONENT_DEPS: () => COMPONENT_DEPS,
37
40
  COMPONENT_PROVIDERS: () => COMPONENT_PROVIDERS,
41
+ COMPONENT_ROUTE: () => COMPONENT_ROUTE,
38
42
  CONTROLLER: () => CONTROLLER,
39
43
  CONTROLLERS_KEY: () => CONTROLLERS_KEY,
40
44
  CONTROLLER_PREFIX_KEY: () => CONTROLLER_PREFIX_KEY,
@@ -44,6 +48,7 @@ var kithinjiorca = (() => {
44
48
  DECLARATIONS_KEY: () => DECLARATIONS_KEY,
45
49
  DESIGN_PARAMTYPES: () => DESIGN_PARAMTYPES,
46
50
  ERROR_ELEMENT: () => ERROR_ELEMENT,
51
+ EVENT_HANDLER: () => EVENT_HANDLER,
47
52
  EXPORTS_KEY: () => EXPORTS_KEY,
48
53
  EXPRESS_ADAPTER_HOST: () => EXPRESS_ADAPTER_HOST,
49
54
  Fragment: () => Fragment,
@@ -76,18 +81,28 @@ var kithinjiorca = (() => {
76
81
  Param: () => Param,
77
82
  Post: () => Post,
78
83
  ProviderNormalizer: () => ProviderNormalizer,
84
+ Query: () => Query,
79
85
  RouterModule: () => RouterModule,
80
86
  RouterOutlet: () => RouterOutlet,
81
87
  SIGNATURE_METADATA_KEY: () => SIGNATURE_METADATA_KEY,
88
+ SSE_ROUTE: () => SSE_ROUTE,
82
89
  Signature: () => Signature,
90
+ Sse: () => Sse,
91
+ Subject: () => Subject,
92
+ Subscribe: () => Subscribe,
83
93
  assert$: () => assert$,
84
94
  batch: () => batch,
85
95
  browser: () => browser_exports,
96
+ catchError: () => catchError,
86
97
  collectAllProvidersFromNode: () => collectAllProvidersFromNode,
87
98
  computed: () => computed,
99
+ concatMap: () => concatMap,
88
100
  createComponent: () => createComponent,
89
101
  createRoot: () => createRoot,
102
+ debounceTime: () => debounceTime,
103
+ distinctUntilChanged: () => distinctUntilChanged,
90
104
  effect: () => effect,
105
+ filter: () => filter,
91
106
  from: () => from,
92
107
  getCurrentInjector: () => getCurrentInjector,
93
108
  getSignatureMetadata: () => getSignatureMetadata,
@@ -101,16 +116,26 @@ var kithinjiorca = (() => {
101
116
  isSignal: () => isSignal,
102
117
  jsx: () => jsx,
103
118
  jsxs: () => jsxs,
119
+ map: () => map,
120
+ mergeMap: () => mergeMap,
104
121
  observable: () => observable,
105
122
  of: () => of,
106
123
  parseSignatureSchemas: () => parseSignatureSchemas,
124
+ reduce: () => reduce,
125
+ scan: () => scan,
107
126
  setCurrentInjector: () => setCurrentInjector,
108
127
  shared: () => shared_exports,
109
128
  signal: () => signal,
129
+ skip: () => skip,
110
130
  spread: () => spread,
131
+ startWith: () => startWith,
111
132
  style: () => style,
133
+ switchMap: () => switchMap,
112
134
  symbolValueReplacer: () => symbolValueReplacer,
113
135
  symbolValueReviver: () => symbolValueReviver,
136
+ take: () => take,
137
+ tap: () => tap,
138
+ throttleTime: () => throttleTime,
114
139
  toSignal: () => toSignal,
115
140
  untracked: () => untracked
116
141
  });
@@ -121,10 +146,13 @@ var kithinjiorca = (() => {
121
146
  __export(shared_exports, {
122
147
  BOOTSTRAP: () => BOOTSTRAP,
123
148
  BOOTSTRAP_VNODE: () => BOOTSTRAP_VNODE,
149
+ BaseActor: () => BaseActor,
150
+ BehaviorSubject: () => BehaviorSubject,
124
151
  Body: () => Body,
125
152
  COMPONENT: () => COMPONENT,
126
153
  COMPONENT_DEPS: () => COMPONENT_DEPS,
127
154
  COMPONENT_PROVIDERS: () => COMPONENT_PROVIDERS,
155
+ COMPONENT_ROUTE: () => COMPONENT_ROUTE,
128
156
  CONTROLLER: () => CONTROLLER,
129
157
  CONTROLLERS_KEY: () => CONTROLLERS_KEY,
130
158
  CONTROLLER_PREFIX_KEY: () => CONTROLLER_PREFIX_KEY,
@@ -134,6 +162,7 @@ var kithinjiorca = (() => {
134
162
  DECLARATIONS_KEY: () => DECLARATIONS_KEY,
135
163
  DESIGN_PARAMTYPES: () => DESIGN_PARAMTYPES,
136
164
  ERROR_ELEMENT: () => ERROR_ELEMENT,
165
+ EVENT_HANDLER: () => EVENT_HANDLER,
137
166
  EXPORTS_KEY: () => EXPORTS_KEY,
138
167
  EXPRESS_ADAPTER_HOST: () => EXPRESS_ADAPTER_HOST,
139
168
  Fragment: () => Fragment,
@@ -151,7 +180,6 @@ var kithinjiorca = (() => {
151
180
  Injector: () => Injector,
152
181
  Module: () => Module,
153
182
  NODE: () => NODE,
154
- Navigate: () => Navigate,
155
183
  Node: () => Node2,
156
184
  ORCA_CLIENT_COMPONENT: () => ORCA_CLIENT_COMPONENT,
157
185
  ORCA_ELEMENT_TYPE: () => ORCA_ELEMENT_TYPE,
@@ -166,19 +194,27 @@ var kithinjiorca = (() => {
166
194
  Param: () => Param,
167
195
  Post: () => Post,
168
196
  ProviderNormalizer: () => ProviderNormalizer,
169
- RouterModule: () => RouterModule,
170
- RouterOutlet: () => RouterOutlet,
197
+ Query: () => Query,
171
198
  SIGNATURE_METADATA_KEY: () => SIGNATURE_METADATA_KEY,
199
+ SSE_ROUTE: () => SSE_ROUTE,
172
200
  Signature: () => Signature,
201
+ Sse: () => Sse,
173
202
  StreamRenderer: () => StreamRenderer,
174
203
  StringRenderer: () => StringRenderer,
204
+ Subject: () => Subject,
205
+ Subscribe: () => Subscribe,
175
206
  VNode: () => VNode,
176
207
  assert$: () => assert$,
177
208
  batch: () => batch,
209
+ catchError: () => catchError,
178
210
  collectAllProvidersFromNode: () => collectAllProvidersFromNode,
179
211
  computed: () => computed,
212
+ concatMap: () => concatMap,
180
213
  createRoot: () => createRoot,
214
+ debounceTime: () => debounceTime,
215
+ distinctUntilChanged: () => distinctUntilChanged,
181
216
  effect: () => effect,
217
+ filter: () => filter,
182
218
  from: () => from,
183
219
  getCurrentInjector: () => getCurrentInjector,
184
220
  getSignatureMetadata: () => getSignatureMetadata,
@@ -191,14 +227,24 @@ var kithinjiorca = (() => {
191
227
  isSignal: () => isSignal,
192
228
  jsx: () => jsx,
193
229
  jsxs: () => jsxs,
230
+ map: () => map,
231
+ mergeMap: () => mergeMap,
194
232
  observable: () => observable,
195
233
  of: () => of,
196
234
  parseSignatureSchemas: () => parseSignatureSchemas,
235
+ reduce: () => reduce,
236
+ scan: () => scan,
197
237
  setCurrentInjector: () => setCurrentInjector,
198
238
  signal: () => signal,
239
+ skip: () => skip,
240
+ startWith: () => startWith,
199
241
  store: () => store,
242
+ switchMap: () => switchMap,
200
243
  symbolValueReplacer: () => symbolValueReplacer,
201
244
  symbolValueReviver: () => symbolValueReviver,
245
+ take: () => take,
246
+ tap: () => tap,
247
+ throttleTime: () => throttleTime,
202
248
  toSignal: () => toSignal,
203
249
  untracked: () => untracked
204
250
  });
@@ -234,6 +280,7 @@ var kithinjiorca = (() => {
234
280
  var COMPONENT = Symbol("orca:component");
235
281
  var COMPONENT_PROVIDERS = Symbol("orca:component:providers");
236
282
  var COMPONENT_DEPS = Symbol("orca:component:deps");
283
+ var COMPONENT_ROUTE = Symbol("orca:component:route");
237
284
  var INJECT_TOKENS_KEY = Symbol("orca:injectTokens");
238
285
  var NODE = Symbol("orca:node");
239
286
  var DESIGN_PARAMTYPES = "design:paramtypes";
@@ -244,6 +291,8 @@ var kithinjiorca = (() => {
244
291
  var PATH_KEY = Symbol("orca:path");
245
292
  var EXPRESS_ADAPTER_HOST = Symbol("orca:express");
246
293
  var SIGNATURE_METADATA_KEY = Symbol("orca:signature:schemas");
294
+ var SSE_ROUTE = Symbol("orca:sse:route");
295
+ var EVENT_HANDLER = Symbol("orca:event:handler");
247
296
  var ERROR_ELEMENT = Symbol.for("orca:error");
248
297
  var ORCA_ELEMENT_TYPE = Symbol.for("orca:element");
249
298
  var ORCA_FRAGMENT_TYPE = Symbol.for("orca:fragment");
@@ -254,6 +303,10 @@ var kithinjiorca = (() => {
254
303
  var HandlerParamType = /* @__PURE__ */ ((HandlerParamType2) => {
255
304
  HandlerParamType2["ROUTE_PARAM"] = "ROUTE_PARAM";
256
305
  HandlerParamType2["BODY"] = "BODY";
306
+ HandlerParamType2["QUERY"] = "QUERY";
307
+ HandlerParamType2["HEADERS"] = "HEADERS";
308
+ HandlerParamType2["REQUEST"] = "REQUEST";
309
+ HandlerParamType2["RESPONSE"] = "RESPONSE";
257
310
  return HandlerParamType2;
258
311
  })(HandlerParamType || {});
259
312
  var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
@@ -270,7 +323,7 @@ var kithinjiorca = (() => {
270
323
  Reflect.defineMetadata(IMPORTS_KEY, params.imports || [], target);
271
324
  Reflect.defineMetadata(EXPORTS_KEY, params.exports || [], target);
272
325
  Reflect.defineMetadata(CONTROLLERS_KEY, params.controllers || [], target);
273
- Reflect.defineMetadata(BOOTSTRAP, params.bootstrap || [], target);
326
+ Reflect.defineMetadata(BOOTSTRAP, params.bootstrap, target);
274
327
  };
275
328
  }
276
329
  function Injectable() {
@@ -284,8 +337,15 @@ var kithinjiorca = (() => {
284
337
  store.update("components", (current) => {
285
338
  const next = current ?? /* @__PURE__ */ new Map();
286
339
  next.set(target.name, target);
340
+ if (params.route) {
341
+ const [pathPattern] = params.route.split("?");
342
+ next.set(pathPattern, target);
343
+ }
287
344
  return next;
288
345
  });
346
+ if (params.route) {
347
+ Reflect.defineMetadata(COMPONENT_ROUTE, params.route, target);
348
+ }
289
349
  Reflect.defineMetadata(COMPONENT, true, target);
290
350
  Reflect.defineMetadata(COMPONENT_PROVIDERS, params.providers || [], target);
291
351
  Reflect.defineMetadata(COMPONENT_DEPS, params.deps || [], target);
@@ -329,6 +389,9 @@ var kithinjiorca = (() => {
329
389
  function Body(key) {
330
390
  return getHandlerParamDecorator("BODY" /* BODY */, key);
331
391
  }
392
+ function Query(key) {
393
+ return getHandlerParamDecorator("QUERY" /* QUERY */, key);
394
+ }
332
395
  function getRouteDecorator(httpMethod, path) {
333
396
  return function(target, key, descriptor) {
334
397
  Reflect.defineMetadata(HTTP_METHOD_KEY, httpMethod, target, key);
@@ -341,6 +404,18 @@ var kithinjiorca = (() => {
341
404
  function Post(path) {
342
405
  return getRouteDecorator("post" /* POST */, path ?? "");
343
406
  }
407
+ function Sse(path) {
408
+ return function(target, propertyKey, descriptor) {
409
+ Reflect.defineMetadata(SSE_ROUTE, true, target, propertyKey);
410
+ Reflect.defineMetadata(PATH_KEY, path, target, propertyKey);
411
+ Reflect.defineMetadata(HTTP_METHOD_KEY, "get" /* GET */, target, propertyKey);
412
+ };
413
+ }
414
+ function Subscribe(pattern) {
415
+ return function(target, propertyKey, descriptor) {
416
+ Reflect.defineMetadata(EVENT_HANDLER, pattern, target, propertyKey);
417
+ };
418
+ }
344
419
  function Signature(...schemas) {
345
420
  return function(target, propertyKey, descriptor) {
346
421
  Reflect.defineMetadata(SIGNATURE_METADATA_KEY, schemas, target, propertyKey);
@@ -488,7 +563,7 @@ var kithinjiorca = (() => {
488
563
  const exportedTokens = node.getExports();
489
564
  for (const exp of exportedTokens) {
490
565
  if (!providedTokens.has(exp)) {
491
- errors.push(`\u274C EXPORT ERROR in module "${moduleName}":
566
+ errors.push(`EXPORT ERROR in module "${moduleName}":
492
567
  Exports token "${tokenName(exp)}" but this module does not provide it.
493
568
  \u2192 Add it to providers/controllers/declarations, or remove from exports.`);
494
569
  }
@@ -496,7 +571,7 @@ var kithinjiorca = (() => {
496
571
  const seen = /* @__PURE__ */ new Set();
497
572
  for (const token of providedTokens.keys()) {
498
573
  if (seen.has(token)) {
499
- errors.push(`\u274C DUPLICATE PROVIDER in module "${moduleName}":
574
+ errors.push(`DUPLICATE PROVIDER in module "${moduleName}":
500
575
  Token "${tokenName(token)}" is registered more than once.
501
576
  \u2192 Remove duplicate entries.`);
502
577
  }
@@ -520,7 +595,7 @@ var kithinjiorca = (() => {
520
595
  suggestion = `
521
596
  \u2192 "${missing}" is not provided anywhere. Add a provider for it.`;
522
597
  }
523
- errors.push(`\u274C UNRESOLVED DEPENDENCY in module "${moduleName}":
598
+ errors.push(`UNRESOLVED DEPENDENCY in module "${moduleName}":
524
599
  "${consumer}" requires "${missing}"${suggestion}`);
525
600
  }
526
601
  }
@@ -530,14 +605,14 @@ var kithinjiorca = (() => {
530
605
  const componentDeps = Reflect.getMetadata(COMPONENT_DEPS, token) || [];
531
606
  componentDeps.forEach((depComp) => {
532
607
  if (typeof depComp === "function" && !Reflect.getMetadata(COMPONENT, depComp)) {
533
- errors.push(`\u274C COMPONENT DEPENDENCY ERROR in module "${moduleName}":
608
+ errors.push(`COMPONENT DEPENDENCY ERROR in module "${moduleName}":
534
609
  Component "${tokenName(token)}" lists "${tokenName(depComp)}" in deps
535
610
  \u2192 "${tokenName(depComp)}" is not a component (missing @Component decorator)`);
536
611
  }
537
612
  if (!providedTokens.has(depComp)) {
538
613
  const providingMod = this.findProvidingModule(depComp, node, allNodes, /* @__PURE__ */ new Set());
539
614
  if (!providingMod) {
540
- errors.push(`\u274C COMPONENT DEPENDENCY ERROR in module "${moduleName}":
615
+ errors.push(`COMPONENT DEPENDENCY ERROR in module "${moduleName}":
541
616
  Component "${tokenName(token)}" renders "${tokenName(depComp)}"
542
617
  \u2192 "${tokenName(depComp)}" must be in declarations or imported`);
543
618
  }
@@ -877,14 +952,14 @@ var kithinjiorca = (() => {
877
952
  return "";
878
953
  }
879
954
  escapeHtml(text) {
880
- const map = {
955
+ const map2 = {
881
956
  "&": "&",
882
957
  "<": "&lt;",
883
958
  ">": "&gt;",
884
959
  '"': "&quot;",
885
960
  "'": "&#039;"
886
961
  };
887
- return text.replace(/[&<>"']/g, (m) => map[m]);
962
+ return text.replace(/[&<>"']/g, (m) => map2[m]);
888
963
  }
889
964
  };
890
965
 
@@ -966,6 +1041,16 @@ var kithinjiorca = (() => {
966
1041
  } else {
967
1042
  processedChildren = this.mapChildren(children, injector);
968
1043
  }
1044
+ if (vnode.type == "a" && restProps["href"]) {
1045
+ const href = restProps["href"];
1046
+ try {
1047
+ new URL(href);
1048
+ } catch {
1049
+ if (!href.startsWith("#") && !href.startsWith("mailto:") && !href.startsWith("tel:")) {
1050
+ restProps["onclick"] = `Orca.navigate(event, '${href}')`;
1051
+ }
1052
+ }
1053
+ }
969
1054
  return {
970
1055
  $$typeof: ORCA_ELEMENT_TYPE,
971
1056
  type: vnode.type,
@@ -1232,10 +1317,11 @@ var kithinjiorca = (() => {
1232
1317
  let value = initialValue;
1233
1318
  const subscribers = /* @__PURE__ */ new Set();
1234
1319
  const notify = () => {
1235
- if (batchDepth > 0) {
1236
- subscribers.forEach((sub) => pendingEffects.add(sub));
1237
- } else {
1238
- subscribers.forEach((sub) => sub.execute());
1320
+ subscribers.forEach((sub) => pendingEffects.add(sub));
1321
+ if (batchDepth === 0) {
1322
+ const effects = Array.from(pendingEffects);
1323
+ pendingEffects.clear();
1324
+ effects.forEach((effect2) => effect2.execute());
1239
1325
  }
1240
1326
  };
1241
1327
  return {
@@ -1355,67 +1441,40 @@ var kithinjiorca = (() => {
1355
1441
  constructor(producer) {
1356
1442
  this.producer = producer;
1357
1443
  this.__isObservable = true;
1358
- this.subscribers = /* @__PURE__ */ new Set();
1359
- }
1360
- get $value() {
1361
- return this._value;
1362
- }
1363
- setValue(newValue) {
1364
- this._value = newValue;
1365
1444
  }
1366
1445
  subscribe(observerOrNext, error, complete) {
1367
1446
  const observer = typeof observerOrNext === "function" ? { next: observerOrNext, error, complete } : observerOrNext;
1368
- this.subscribers.add(observer);
1369
1447
  let cleanup;
1448
+ let isUnsubscribed = false;
1370
1449
  if (this.producer) {
1371
1450
  try {
1372
1451
  cleanup = this.producer(observer);
1373
1452
  } catch (err) {
1374
1453
  if (observer.error) {
1375
- observer.error(err);
1454
+ try {
1455
+ observer.error(err);
1456
+ } catch (e) {
1457
+ console.error("Error in error handler during subscription:", e);
1458
+ }
1459
+ } else {
1460
+ throw err;
1376
1461
  }
1377
1462
  }
1378
1463
  }
1379
1464
  return {
1380
1465
  unsubscribe: () => {
1381
- this.subscribers.delete(observer);
1382
- if (cleanup)
1383
- cleanup();
1384
- }
1385
- };
1386
- }
1387
- next(value) {
1388
- this.setValue(value);
1389
- this.subscribers.forEach((observer) => {
1390
- try {
1391
- observer.next(value);
1392
- } catch (err) {
1393
- console.error("Error in observer:", err);
1394
- }
1395
- });
1396
- }
1397
- error(err) {
1398
- this.subscribers.forEach((observer) => {
1399
- if (observer.error) {
1400
- try {
1401
- observer.error(err);
1402
- } catch (e) {
1403
- console.error("Error in error handler:", e);
1404
- }
1405
- }
1406
- });
1407
- }
1408
- complete() {
1409
- this.subscribers.forEach((observer) => {
1410
- if (observer.complete) {
1411
- try {
1412
- observer.complete();
1413
- } catch (err) {
1414
- console.error("Error in complete handler:", err);
1466
+ if (isUnsubscribed)
1467
+ return;
1468
+ isUnsubscribed = true;
1469
+ if (cleanup) {
1470
+ try {
1471
+ cleanup();
1472
+ } catch (err) {
1473
+ console.error("Error during cleanup:", err);
1474
+ }
1415
1475
  }
1416
1476
  }
1417
- });
1418
- this.subscribers.clear();
1477
+ };
1419
1478
  }
1420
1479
  pipe(...operations) {
1421
1480
  if (operations.length === 0) {
@@ -1426,10 +1485,14 @@ var kithinjiorca = (() => {
1426
1485
  };
1427
1486
  function from(iterable) {
1428
1487
  return new Observable((observer) => {
1429
- for (const value of iterable) {
1430
- observer.next(value);
1488
+ try {
1489
+ for (const value of iterable) {
1490
+ observer.next(value);
1491
+ }
1492
+ observer.complete?.();
1493
+ } catch (err) {
1494
+ observer.error?.(err);
1431
1495
  }
1432
- observer.complete?.();
1433
1496
  });
1434
1497
  }
1435
1498
  function interval(ms) {
@@ -1443,8 +1506,12 @@ var kithinjiorca = (() => {
1443
1506
  }
1444
1507
  function of(...values) {
1445
1508
  return new Observable((observer) => {
1446
- values.forEach((value) => observer.next(value));
1447
- observer.complete?.();
1509
+ try {
1510
+ values.forEach((value) => observer.next(value));
1511
+ observer.complete?.();
1512
+ } catch (err) {
1513
+ observer.error?.(err);
1514
+ }
1448
1515
  });
1449
1516
  }
1450
1517
  function observable(producer) {
@@ -1455,19 +1522,494 @@ var kithinjiorca = (() => {
1455
1522
  const subst = obs.subscribe((val) => {
1456
1523
  sig.value = val;
1457
1524
  });
1458
- instance.__cleanup = [...instance.__cleanup ?? [], () => subst.unsubscribe()];
1525
+ instance.__cleanup = [
1526
+ ...instance.__cleanup || [],
1527
+ () => subst.unsubscribe()
1528
+ ];
1459
1529
  return sig;
1460
1530
  }
1461
1531
  function isObservable(value) {
1462
1532
  return value && value.__isObservable === true;
1463
1533
  }
1534
+ function map(fn) {
1535
+ return (source) => {
1536
+ return new Observable((observer) => {
1537
+ const subscription = source.subscribe(
1538
+ (value) => {
1539
+ try {
1540
+ observer.next(fn(value));
1541
+ } catch (err) {
1542
+ observer.error?.(err);
1543
+ }
1544
+ },
1545
+ (err) => observer.error?.(err),
1546
+ () => observer.complete?.()
1547
+ );
1548
+ return () => subscription.unsubscribe();
1549
+ });
1550
+ };
1551
+ }
1552
+ function filter(predicate) {
1553
+ return (source) => {
1554
+ return new Observable((observer) => {
1555
+ const subscription = source.subscribe(
1556
+ (value) => {
1557
+ try {
1558
+ if (predicate(value)) {
1559
+ observer.next(value);
1560
+ }
1561
+ } catch (err) {
1562
+ observer.error?.(err);
1563
+ }
1564
+ },
1565
+ (err) => observer.error?.(err),
1566
+ () => observer.complete?.()
1567
+ );
1568
+ return () => subscription.unsubscribe();
1569
+ });
1570
+ };
1571
+ }
1572
+ function tap(fn) {
1573
+ return (source) => {
1574
+ return new Observable((observer) => {
1575
+ const subscription = source.subscribe(
1576
+ (value) => {
1577
+ try {
1578
+ fn(value);
1579
+ observer.next(value);
1580
+ } catch (err) {
1581
+ observer.error?.(err);
1582
+ }
1583
+ },
1584
+ (err) => observer.error?.(err),
1585
+ () => observer.complete?.()
1586
+ );
1587
+ return () => subscription.unsubscribe();
1588
+ });
1589
+ };
1590
+ }
1591
+ function take(count) {
1592
+ return (source) => {
1593
+ return new Observable((observer) => {
1594
+ let taken = 0;
1595
+ const subscription = source.subscribe(
1596
+ (value) => {
1597
+ if (taken < count) {
1598
+ observer.next(value);
1599
+ taken++;
1600
+ if (taken === count) {
1601
+ observer.complete?.();
1602
+ subscription.unsubscribe();
1603
+ }
1604
+ }
1605
+ },
1606
+ (err) => observer.error?.(err),
1607
+ () => observer.complete?.()
1608
+ );
1609
+ return () => subscription.unsubscribe();
1610
+ });
1611
+ };
1612
+ }
1613
+ function skip(count) {
1614
+ return (source) => {
1615
+ return new Observable((observer) => {
1616
+ let skipped = 0;
1617
+ const subscription = source.subscribe(
1618
+ (value) => {
1619
+ if (skipped < count) {
1620
+ skipped++;
1621
+ } else {
1622
+ observer.next(value);
1623
+ }
1624
+ },
1625
+ (err) => observer.error?.(err),
1626
+ () => observer.complete?.()
1627
+ );
1628
+ return () => subscription.unsubscribe();
1629
+ });
1630
+ };
1631
+ }
1632
+ function debounceTime(ms) {
1633
+ return (source) => {
1634
+ return new Observable((observer) => {
1635
+ let timeoutId;
1636
+ const subscription = source.subscribe(
1637
+ (value) => {
1638
+ clearTimeout(timeoutId);
1639
+ timeoutId = setTimeout(() => {
1640
+ observer.next(value);
1641
+ }, ms);
1642
+ },
1643
+ (err) => observer.error?.(err),
1644
+ () => observer.complete?.()
1645
+ );
1646
+ return () => {
1647
+ clearTimeout(timeoutId);
1648
+ subscription.unsubscribe();
1649
+ };
1650
+ });
1651
+ };
1652
+ }
1653
+ function throttleTime(ms) {
1654
+ return (source) => {
1655
+ return new Observable((observer) => {
1656
+ let lastEmit = 0;
1657
+ const subscription = source.subscribe(
1658
+ (value) => {
1659
+ const now = Date.now();
1660
+ if (now - lastEmit >= ms) {
1661
+ lastEmit = now;
1662
+ observer.next(value);
1663
+ }
1664
+ },
1665
+ (err) => observer.error?.(err),
1666
+ () => observer.complete?.()
1667
+ );
1668
+ return () => subscription.unsubscribe();
1669
+ });
1670
+ };
1671
+ }
1672
+ function distinctUntilChanged(compare) {
1673
+ return (source) => {
1674
+ return new Observable((observer) => {
1675
+ let hasLast = false;
1676
+ let last;
1677
+ const subscription = source.subscribe(
1678
+ (value) => {
1679
+ const isDistinct = !hasLast || (compare ? !compare(last, value) : last !== value);
1680
+ if (isDistinct) {
1681
+ hasLast = true;
1682
+ last = value;
1683
+ observer.next(value);
1684
+ }
1685
+ },
1686
+ (err) => observer.error?.(err),
1687
+ () => observer.complete?.()
1688
+ );
1689
+ return () => subscription.unsubscribe();
1690
+ });
1691
+ };
1692
+ }
1693
+ function switchMap(fn) {
1694
+ return (source) => {
1695
+ return new Observable((observer) => {
1696
+ let innerSubscription = null;
1697
+ const outerSubscription = source.subscribe(
1698
+ (value) => {
1699
+ if (innerSubscription) {
1700
+ innerSubscription.unsubscribe();
1701
+ }
1702
+ try {
1703
+ const innerObservable = fn(value);
1704
+ innerSubscription = innerObservable.subscribe(
1705
+ (innerValue) => observer.next(innerValue),
1706
+ (err) => observer.error?.(err)
1707
+ );
1708
+ } catch (err) {
1709
+ observer.error?.(err);
1710
+ }
1711
+ },
1712
+ (err) => observer.error?.(err),
1713
+ () => observer.complete?.()
1714
+ );
1715
+ return () => {
1716
+ if (innerSubscription) {
1717
+ innerSubscription.unsubscribe();
1718
+ }
1719
+ outerSubscription.unsubscribe();
1720
+ };
1721
+ });
1722
+ };
1723
+ }
1724
+ function mergeMap(fn) {
1725
+ return (source) => {
1726
+ return new Observable((observer) => {
1727
+ const innerSubscriptions = [];
1728
+ let outerComplete = false;
1729
+ let activeCount = 0;
1730
+ const checkComplete = () => {
1731
+ if (outerComplete && activeCount === 0) {
1732
+ observer.complete?.();
1733
+ }
1734
+ };
1735
+ const outerSubscription = source.subscribe(
1736
+ (value) => {
1737
+ try {
1738
+ const innerObservable = fn(value);
1739
+ activeCount++;
1740
+ const innerSub = innerObservable.subscribe(
1741
+ (innerValue) => observer.next(innerValue),
1742
+ (err) => observer.error?.(err),
1743
+ () => {
1744
+ activeCount--;
1745
+ checkComplete();
1746
+ }
1747
+ );
1748
+ innerSubscriptions.push(innerSub);
1749
+ } catch (err) {
1750
+ observer.error?.(err);
1751
+ }
1752
+ },
1753
+ (err) => observer.error?.(err),
1754
+ () => {
1755
+ outerComplete = true;
1756
+ checkComplete();
1757
+ }
1758
+ );
1759
+ return () => {
1760
+ innerSubscriptions.forEach((sub) => sub.unsubscribe());
1761
+ outerSubscription.unsubscribe();
1762
+ };
1763
+ });
1764
+ };
1765
+ }
1766
+ function concatMap(fn) {
1767
+ return (source) => {
1768
+ return new Observable((observer) => {
1769
+ const queue = [];
1770
+ let innerSubscription = null;
1771
+ let outerComplete = false;
1772
+ let isProcessing = false;
1773
+ const processNext = () => {
1774
+ if (isProcessing || queue.length === 0) {
1775
+ if (outerComplete && queue.length === 0) {
1776
+ observer.complete?.();
1777
+ }
1778
+ return;
1779
+ }
1780
+ isProcessing = true;
1781
+ const value = queue.shift();
1782
+ try {
1783
+ const innerObservable = fn(value);
1784
+ innerSubscription = innerObservable.subscribe(
1785
+ (innerValue) => observer.next(innerValue),
1786
+ (err) => observer.error?.(err),
1787
+ () => {
1788
+ isProcessing = false;
1789
+ processNext();
1790
+ }
1791
+ );
1792
+ } catch (err) {
1793
+ observer.error?.(err);
1794
+ }
1795
+ };
1796
+ const outerSubscription = source.subscribe(
1797
+ (value) => {
1798
+ queue.push(value);
1799
+ processNext();
1800
+ },
1801
+ (err) => observer.error?.(err),
1802
+ () => {
1803
+ outerComplete = true;
1804
+ if (queue.length === 0 && !isProcessing) {
1805
+ observer.complete?.();
1806
+ }
1807
+ }
1808
+ );
1809
+ return () => {
1810
+ if (innerSubscription) {
1811
+ innerSubscription.unsubscribe();
1812
+ }
1813
+ outerSubscription.unsubscribe();
1814
+ };
1815
+ });
1816
+ };
1817
+ }
1818
+ function catchError(handler) {
1819
+ return (source) => {
1820
+ return new Observable((observer) => {
1821
+ const subscription = source.subscribe(
1822
+ (value) => observer.next(value),
1823
+ (err) => {
1824
+ try {
1825
+ const fallback = handler(err);
1826
+ const fallbackSub = fallback.subscribe(
1827
+ (value) => observer.next(value),
1828
+ (e) => observer.error?.(e),
1829
+ () => observer.complete?.()
1830
+ );
1831
+ subscription.__fallback = fallbackSub;
1832
+ } catch (e) {
1833
+ observer.error?.(e);
1834
+ }
1835
+ },
1836
+ () => observer.complete?.()
1837
+ );
1838
+ return () => {
1839
+ if (subscription.__fallback) {
1840
+ subscription.__fallback.unsubscribe();
1841
+ }
1842
+ subscription.unsubscribe();
1843
+ };
1844
+ });
1845
+ };
1846
+ }
1847
+ function startWith(...values) {
1848
+ return (source) => {
1849
+ return new Observable((observer) => {
1850
+ values.forEach((value) => observer.next(value));
1851
+ const subscription = source.subscribe(
1852
+ (value) => observer.next(value),
1853
+ (err) => observer.error?.(err),
1854
+ () => observer.complete?.()
1855
+ );
1856
+ return () => subscription.unsubscribe();
1857
+ });
1858
+ };
1859
+ }
1860
+ function scan(accumulator, seed) {
1861
+ return (source) => {
1862
+ return new Observable((observer) => {
1863
+ let acc = seed;
1864
+ const subscription = source.subscribe(
1865
+ (value) => {
1866
+ try {
1867
+ acc = accumulator(acc, value);
1868
+ observer.next(acc);
1869
+ } catch (err) {
1870
+ observer.error?.(err);
1871
+ }
1872
+ },
1873
+ (err) => observer.error?.(err),
1874
+ () => observer.complete?.()
1875
+ );
1876
+ return () => subscription.unsubscribe();
1877
+ });
1878
+ };
1879
+ }
1880
+ function reduce(accumulator, seed) {
1881
+ return (source) => {
1882
+ return new Observable((observer) => {
1883
+ let acc = seed;
1884
+ const subscription = source.subscribe(
1885
+ (value) => {
1886
+ try {
1887
+ acc = accumulator(acc, value);
1888
+ } catch (err) {
1889
+ observer.error?.(err);
1890
+ }
1891
+ },
1892
+ (err) => observer.error?.(err),
1893
+ () => {
1894
+ observer.next(acc);
1895
+ observer.complete?.();
1896
+ }
1897
+ );
1898
+ return () => subscription.unsubscribe();
1899
+ });
1900
+ };
1901
+ }
1902
+
1903
+ // src/shared/observable/subject.ts
1904
+ var Subject = class extends Observable {
1905
+ constructor() {
1906
+ super();
1907
+ this.subscribers = /* @__PURE__ */ new Set();
1908
+ this._isCompleted = false;
1909
+ this._hasError = false;
1910
+ }
1911
+ subscribe(observerOrNext, error, complete) {
1912
+ if (this._isCompleted) {
1913
+ const obs = typeof observerOrNext === "function" ? { complete } : observerOrNext;
1914
+ obs.complete?.();
1915
+ return { unsubscribe: () => {
1916
+ } };
1917
+ }
1918
+ if (this._hasError) {
1919
+ return { unsubscribe: () => {
1920
+ } };
1921
+ }
1922
+ const observer = typeof observerOrNext === "function" ? { next: observerOrNext, error, complete } : observerOrNext;
1923
+ this.subscribers.add(observer);
1924
+ return {
1925
+ unsubscribe: () => {
1926
+ this.subscribers.delete(observer);
1927
+ }
1928
+ };
1929
+ }
1930
+ next(value) {
1931
+ if (this._isCompleted || this._hasError)
1932
+ return;
1933
+ const currentSubscribers = Array.from(this.subscribers);
1934
+ currentSubscribers.forEach((observer) => {
1935
+ if (this.subscribers.has(observer)) {
1936
+ try {
1937
+ observer.next(value);
1938
+ } catch (err) {
1939
+ console.error("Error in observer:", err);
1940
+ }
1941
+ }
1942
+ });
1943
+ }
1944
+ error(err) {
1945
+ if (this._isCompleted || this._hasError)
1946
+ return;
1947
+ this._hasError = true;
1948
+ const currentSubscribers = Array.from(this.subscribers);
1949
+ currentSubscribers.forEach((observer) => {
1950
+ if (observer.error) {
1951
+ try {
1952
+ observer.error(err);
1953
+ } catch (e) {
1954
+ console.error("Error in error handler:", e);
1955
+ }
1956
+ }
1957
+ });
1958
+ this.subscribers.clear();
1959
+ }
1960
+ complete() {
1961
+ if (this._isCompleted || this._hasError)
1962
+ return;
1963
+ this._isCompleted = true;
1964
+ const currentSubscribers = Array.from(this.subscribers);
1965
+ currentSubscribers.forEach((observer) => {
1966
+ if (observer.complete) {
1967
+ try {
1968
+ observer.complete();
1969
+ } catch (err) {
1970
+ console.error("Error in complete handler:", err);
1971
+ }
1972
+ }
1973
+ });
1974
+ this.subscribers.clear();
1975
+ }
1976
+ };
1977
+
1978
+ // src/shared/observable/bsubject.ts
1979
+ var BehaviorSubject = class extends Subject {
1980
+ constructor(initialValue) {
1981
+ super();
1982
+ this._value = initialValue;
1983
+ }
1984
+ get $value() {
1985
+ return this._value;
1986
+ }
1987
+ setValue(value) {
1988
+ this._value = value;
1989
+ }
1990
+ next(value) {
1991
+ this._value = value;
1992
+ super.next(value);
1993
+ }
1994
+ subscribe(observerOrNext, error, complete) {
1995
+ const observer = typeof observerOrNext === "function" ? { next: observerOrNext, error, complete } : observerOrNext;
1996
+ try {
1997
+ observer.next(this._value);
1998
+ } catch (err) {
1999
+ if (observer.error) {
2000
+ observer.error(err);
2001
+ }
2002
+ }
2003
+ return super.subscribe(observer);
2004
+ }
2005
+ };
1464
2006
 
1465
2007
  // src/shared/component.ts
1466
2008
  var OrcaComponent = class {
1467
2009
  constructor() {
1468
2010
  this.__cleanup = [];
1469
2011
  }
1470
- onDestory() {
2012
+ onDestroy() {
1471
2013
  this.__cleanup.forEach((cb) => cb());
1472
2014
  }
1473
2015
  pushDrop(fn) {
@@ -1475,7 +2017,7 @@ var kithinjiorca = (() => {
1475
2017
  }
1476
2018
  };
1477
2019
 
1478
- // src/shared/module_libs/router_module/navigate.ts
2020
+ // src/shared/module_libs/http_client/module.ts
1479
2021
  var __decorate = function(decorators, target, key, desc) {
1480
2022
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1481
2023
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -1486,162 +2028,6 @@ var kithinjiorca = (() => {
1486
2028
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1487
2029
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1488
2030
  };
1489
- var __metadata = function(k, v) {
1490
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
1491
- return Reflect.metadata(k, v);
1492
- };
1493
- var __param = function(paramIndex, decorator) {
1494
- return function(target, key) {
1495
- decorator(target, key, paramIndex);
1496
- };
1497
- };
1498
- var Navigate = class Navigate2 {
1499
- constructor(oscUrl) {
1500
- this.oscUrl = oscUrl;
1501
- this.pages = from([]);
1502
- this.cursor = 0;
1503
- const initialState = history.state?.cursor ?? 0;
1504
- this.cursor = initialState;
1505
- if (!history.state) {
1506
- history.replaceState({ cursor: 0 }, "");
1507
- }
1508
- window.addEventListener("popstate", (e) => {
1509
- const newIndex = e.state?.cursor ?? 0;
1510
- this.cursor = newIndex;
1511
- this.pages.next([...this.pages.$value || []]);
1512
- });
1513
- }
1514
- getHome() {
1515
- const http = new HttpClient();
1516
- return http.post(this.oscUrl, {
1517
- stream: "ndjson",
1518
- reviver: symbolValueReviver
1519
- });
1520
- }
1521
- push(component) {
1522
- const currentPages = this.pages.$value || [];
1523
- const newPages = currentPages.slice(0, this.cursor + 1);
1524
- this.cursor++;
1525
- newPages.push(component);
1526
- history.pushState({ cursor: this.cursor }, "");
1527
- this.pages.next(newPages);
1528
- }
1529
- replace(component) {
1530
- const currentPages = [...this.pages.$value || []];
1531
- currentPages[this.cursor] = component;
1532
- history.replaceState({ cursor: this.cursor }, "");
1533
- this.pages.next(currentPages);
1534
- }
1535
- goBack() {
1536
- if (this.cursor > 0) {
1537
- history.back();
1538
- }
1539
- }
1540
- goForward() {
1541
- const currentPages = this.pages.$value || [];
1542
- if (this.cursor < currentPages.length - 1) {
1543
- history.forward();
1544
- }
1545
- }
1546
- canGoBack() {
1547
- return this.cursor > 0;
1548
- }
1549
- canGoForward() {
1550
- const currentPages = this.pages.$value || [];
1551
- return this.cursor < currentPages.length - 1;
1552
- }
1553
- getCurrentPage() {
1554
- const currentPages = this.pages.$value || [];
1555
- return currentPages[this.cursor];
1556
- }
1557
- clear() {
1558
- this.cursor = 0;
1559
- this.pages.next([]);
1560
- history.replaceState({ cursor: 0 }, "");
1561
- }
1562
- };
1563
- Navigate = __decorate([
1564
- __param(0, Inject("OSC_URL", { maybe: true })),
1565
- __metadata("design:paramtypes", [String])
1566
- ], Navigate);
1567
-
1568
- // src/shared/module_libs/router_module/outlet.ts
1569
- var __decorate2 = function(decorators, target, key, desc) {
1570
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1571
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
1572
- r = Reflect.decorate(decorators, target, key, desc);
1573
- else
1574
- for (var i = decorators.length - 1; i >= 0; i--)
1575
- if (d = decorators[i])
1576
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1577
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1578
- };
1579
- var __metadata2 = function(k, v) {
1580
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
1581
- return Reflect.metadata(k, v);
1582
- };
1583
- var _a;
1584
- var RouterOutlet = class RouterOutlet2 extends OrcaComponent {
1585
- constructor(navigate) {
1586
- super();
1587
- this.navigate = navigate;
1588
- }
1589
- build() {
1590
- const anchor = document.createElement("div");
1591
- const root = document.createElement("div");
1592
- anchor.appendChild(root);
1593
- const osc = new OSC(root);
1594
- const stream = this.navigate.getHome();
1595
- const streamSubscription = stream.subscribe((jsx2) => {
1596
- const action = jsx2.action || "insert";
1597
- if (action === "insert") {
1598
- osc.handleInsert(jsx2);
1599
- } else if (action === "update") {
1600
- osc.handleUpdate(jsx2);
1601
- } else {
1602
- console.warn(`Unknown action: ${action}`);
1603
- }
1604
- }, () => {
1605
- }, () => {
1606
- this.navigate.pages.setValue([osc.tree.dom]);
1607
- });
1608
- const subscription = this.navigate.pages.subscribe((pages) => {
1609
- const top = pages[this.navigate.cursor];
1610
- anchor.replaceChildren(top);
1611
- });
1612
- this.pushDrop(() => subscription.unsubscribe());
1613
- this.pushDrop(() => streamSubscription.unsubscribe());
1614
- return anchor;
1615
- }
1616
- };
1617
- RouterOutlet = __decorate2([
1618
- Component(),
1619
- __metadata2("design:paramtypes", [typeof (_a = typeof Navigate !== "undefined" && Navigate) === "function" ? _a : Object])
1620
- ], RouterOutlet);
1621
-
1622
- // src/shared/module_libs/router_module/module.ts
1623
- var RouterModule = class _RouterModule {
1624
- static forRoot() {
1625
- return {
1626
- module: _RouterModule,
1627
- declarations: [RouterOutlet],
1628
- providers: [Navigate],
1629
- exports: [Navigate, RouterOutlet]
1630
- };
1631
- }
1632
- };
1633
-
1634
- // src/shared/module_libs/http_client/module.ts
1635
- var __decorate3 = function(decorators, target, key, desc) {
1636
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1637
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
1638
- r = Reflect.decorate(decorators, target, key, desc);
1639
- else
1640
- for (var i = decorators.length - 1; i >= 0; i--)
1641
- if (d = decorators[i])
1642
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1643
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1644
- };
1645
2031
  var HttpClient = class HttpClient2 {
1646
2032
  get(url, { stream = "json", reviver, init } = {}) {
1647
2033
  return new Observable((subscriber) => {
@@ -1765,12 +2151,12 @@ var kithinjiorca = (() => {
1765
2151
  });
1766
2152
  }
1767
2153
  };
1768
- HttpClient = __decorate3([
2154
+ HttpClient = __decorate([
1769
2155
  Injectable()
1770
2156
  ], HttpClient);
1771
2157
  var HttpClientModule = class HttpClientModule2 {
1772
2158
  };
1773
- HttpClientModule = __decorate3([
2159
+ HttpClientModule = __decorate([
1774
2160
  Module({
1775
2161
  providers: [HttpClient],
1776
2162
  exports: [HttpClient]
@@ -2029,47 +2415,415 @@ var kithinjiorca = (() => {
2029
2415
  return context?.factory.createStringLiteral("assert");
2030
2416
  }
2031
2417
 
2418
+ // src/shared/providers/actor.ts
2419
+ var BaseActor = class {
2420
+ constructor() {
2421
+ this.mailbox = [];
2422
+ this.isProcessing = false;
2423
+ this.subscribers = /* @__PURE__ */ new Map();
2424
+ }
2425
+ receive(message) {
2426
+ this.mailbox.push(message);
2427
+ this.process();
2428
+ }
2429
+ subscribe(tag, handler) {
2430
+ if (!this.subscribers.has(tag)) {
2431
+ this.subscribers.set(tag, []);
2432
+ }
2433
+ this.subscribers.get(tag).push(handler);
2434
+ }
2435
+ unsubscribe(tag, handler) {
2436
+ const handlers = this.subscribers.get(tag);
2437
+ if (handlers) {
2438
+ const index = handlers.indexOf(handler);
2439
+ if (index > -1) {
2440
+ handlers.splice(index, 1);
2441
+ }
2442
+ }
2443
+ }
2444
+ async process() {
2445
+ if (this.isProcessing)
2446
+ return;
2447
+ this.isProcessing = true;
2448
+ while (this.mailbox.length > 0) {
2449
+ const message = this.mailbox.shift();
2450
+ const handlers = this.subscribers.get(message.event);
2451
+ if (handlers) {
2452
+ for (const handler of handlers) {
2453
+ await handler(message);
2454
+ }
2455
+ }
2456
+ }
2457
+ this.isProcessing = false;
2458
+ }
2459
+ };
2460
+
2032
2461
  // src/browser/index.ts
2033
2462
  var browser_exports = {};
2034
2463
  __export(browser_exports, {
2464
+ Actor: () => Actor,
2465
+ ActorModule: () => ActorModule,
2035
2466
  BrowserFactory: () => BrowserFactory,
2467
+ Navigate: () => Navigate,
2468
+ RouterModule: () => RouterModule,
2469
+ RouterOutlet: () => RouterOutlet,
2036
2470
  createComponent: () => createComponent,
2037
2471
  insert: () => insert,
2038
2472
  spread: () => spread,
2039
2473
  style: () => style
2040
2474
  });
2041
2475
 
2476
+ // src/browser/modules/actor/actor.ts
2477
+ var import_socket = __require("socket.io-client");
2478
+ var __decorate2 = function(decorators, target, key, desc) {
2479
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2480
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2481
+ r = Reflect.decorate(decorators, target, key, desc);
2482
+ else
2483
+ for (var i = decorators.length - 1; i >= 0; i--)
2484
+ if (d = decorators[i])
2485
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2486
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2487
+ };
2488
+ var __metadata = function(k, v) {
2489
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
2490
+ return Reflect.metadata(k, v);
2491
+ };
2492
+ var Actor = class Actor2 extends BaseActor {
2493
+ constructor() {
2494
+ super();
2495
+ this.pending = [];
2496
+ this.socket = (0, import_socket.io)();
2497
+ this.socket.on("connect", () => {
2498
+ this.flushPending();
2499
+ });
2500
+ this.socket.on("message", (message) => {
2501
+ this.receive(message);
2502
+ });
2503
+ }
2504
+ send(to, message) {
2505
+ const payload = {
2506
+ to,
2507
+ from: this.socket.id,
2508
+ ...message
2509
+ };
2510
+ if (this.socket.connected && this.socket.id) {
2511
+ this.socket.emit("message", payload);
2512
+ } else {
2513
+ this.pending.push(payload);
2514
+ }
2515
+ }
2516
+ flushPending() {
2517
+ if (!this.socket.id)
2518
+ return;
2519
+ for (const msg of this.pending) {
2520
+ msg.from = this.socket.id;
2521
+ this.socket.emit("message", msg);
2522
+ }
2523
+ this.pending = [];
2524
+ }
2525
+ };
2526
+ Actor = __decorate2([
2527
+ Injectable(),
2528
+ __metadata("design:paramtypes", [])
2529
+ ], Actor);
2530
+ var ActorModule = class _ActorModule {
2531
+ static forRoot() {
2532
+ return {
2533
+ module: _ActorModule,
2534
+ providers: [
2535
+ {
2536
+ provide: Actor,
2537
+ useClass: Actor,
2538
+ eager: true
2539
+ }
2540
+ ],
2541
+ exports: [Actor]
2542
+ };
2543
+ }
2544
+ };
2545
+
2546
+ // src/browser/modules/router_module/navigate.ts
2547
+ var __decorate3 = function(decorators, target, key, desc) {
2548
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2549
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2550
+ r = Reflect.decorate(decorators, target, key, desc);
2551
+ else
2552
+ for (var i = decorators.length - 1; i >= 0; i--)
2553
+ if (d = decorators[i])
2554
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2555
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2556
+ };
2557
+ var __metadata2 = function(k, v) {
2558
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
2559
+ return Reflect.metadata(k, v);
2560
+ };
2561
+ var __param = function(paramIndex, decorator) {
2562
+ return function(target, key) {
2563
+ decorator(target, key, paramIndex);
2564
+ };
2565
+ };
2566
+ var Navigate = class Navigate2 {
2567
+ constructor(oscUrl) {
2568
+ this.oscUrl = oscUrl;
2569
+ this.cursor = 0;
2570
+ const initialStream = this.createStreamForCurrentUrl();
2571
+ this.pages = new BehaviorSubject([initialStream]);
2572
+ history.replaceState({ cursor: 0 }, "");
2573
+ window.addEventListener("popstate", (e) => {
2574
+ const newIndex = e.state?.cursor ?? 0;
2575
+ this.cursor = newIndex;
2576
+ this.pages.next([...this.pages.$value || []]);
2577
+ });
2578
+ }
2579
+ createStreamForCurrentUrl() {
2580
+ const http = new HttpClient();
2581
+ let url = this.oscUrl;
2582
+ const path = window.location.pathname;
2583
+ const search = window.location.search;
2584
+ if (path !== "/") {
2585
+ const fullRoute = search ? `${path}${search}` : path;
2586
+ url = `${this.oscUrl}?c=${encodeURIComponent(fullRoute)}`;
2587
+ }
2588
+ return http.post(url, {
2589
+ stream: "ndjson",
2590
+ reviver: symbolValueReviver
2591
+ });
2592
+ }
2593
+ go(path) {
2594
+ const http = new HttpClient();
2595
+ const stream = http.post(`${this.oscUrl}?c=${path}`, {
2596
+ stream: "ndjson",
2597
+ reviver: symbolValueReviver
2598
+ });
2599
+ stream.__route = path;
2600
+ this.push(stream);
2601
+ }
2602
+ push(item) {
2603
+ const currentPages = this.pages.$value || [];
2604
+ const newPages = currentPages.slice(0, this.cursor + 1);
2605
+ let route = "";
2606
+ if (item && typeof item === "object" && "__route" in item) {
2607
+ route = item.__route;
2608
+ }
2609
+ this.cursor++;
2610
+ newPages.push(item);
2611
+ history.pushState({ cursor: this.cursor }, "", route);
2612
+ this.pages.next(newPages);
2613
+ }
2614
+ replace(item) {
2615
+ const currentPages = [...this.pages.$value || []];
2616
+ currentPages[this.cursor] = item;
2617
+ history.replaceState({ cursor: this.cursor }, "");
2618
+ this.pages.next(currentPages);
2619
+ }
2620
+ resolveStream(index, element) {
2621
+ const currentPages = [...this.pages.$value || []];
2622
+ if (index >= 0 && index < currentPages.length) {
2623
+ currentPages[index] = element;
2624
+ this.pages.next(currentPages);
2625
+ }
2626
+ }
2627
+ goBack() {
2628
+ if (this.cursor > 0) {
2629
+ history.back();
2630
+ }
2631
+ }
2632
+ goForward() {
2633
+ const currentPages = this.pages.$value || [];
2634
+ if (this.cursor < currentPages.length - 1) {
2635
+ history.forward();
2636
+ }
2637
+ }
2638
+ canGoBack() {
2639
+ return this.cursor > 0;
2640
+ }
2641
+ canGoForward() {
2642
+ const currentPages = this.pages.$value || [];
2643
+ return this.cursor < currentPages.length - 1;
2644
+ }
2645
+ getCurrentPage() {
2646
+ const currentPages = this.pages.$value || [];
2647
+ return currentPages[this.cursor];
2648
+ }
2649
+ clear() {
2650
+ this.cursor = 0;
2651
+ this.pages.next([]);
2652
+ history.replaceState({ cursor: 0 }, "");
2653
+ }
2654
+ };
2655
+ Navigate = __decorate3([
2656
+ __param(0, Inject("OSC_URL", { maybe: true })),
2657
+ __metadata2("design:paramtypes", [String])
2658
+ ], Navigate);
2659
+
2660
+ // src/browser/modules/router_module/outlet.ts
2661
+ var __decorate4 = function(decorators, target, key, desc) {
2662
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2663
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2664
+ r = Reflect.decorate(decorators, target, key, desc);
2665
+ else
2666
+ for (var i = decorators.length - 1; i >= 0; i--)
2667
+ if (d = decorators[i])
2668
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2669
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2670
+ };
2671
+ var __metadata3 = function(k, v) {
2672
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
2673
+ return Reflect.metadata(k, v);
2674
+ };
2675
+ var _a;
2676
+ var RouterOutlet = class RouterOutlet2 extends OrcaComponent {
2677
+ constructor(navigate) {
2678
+ super();
2679
+ this.navigate = navigate;
2680
+ this.activeStreamSubscription = null;
2681
+ }
2682
+ build() {
2683
+ const anchor = document.createElement("div");
2684
+ const subscription = this.navigate.pages.subscribe((pages) => {
2685
+ this.renderCurrentPage(anchor, pages);
2686
+ });
2687
+ this.pushDrop(() => subscription.unsubscribe());
2688
+ this.pushDrop(() => {
2689
+ if (this.activeStreamSubscription) {
2690
+ this.activeStreamSubscription.unsubscribe();
2691
+ }
2692
+ });
2693
+ return anchor;
2694
+ }
2695
+ renderCurrentPage(anchor, pages) {
2696
+ const currentItem = pages[this.navigate.cursor];
2697
+ if (!currentItem) {
2698
+ anchor.replaceChildren();
2699
+ return;
2700
+ }
2701
+ if (this.activeStreamSubscription) {
2702
+ this.activeStreamSubscription.unsubscribe();
2703
+ this.activeStreamSubscription = null;
2704
+ }
2705
+ if (this.isObservable(currentItem)) {
2706
+ this.renderStream(anchor, currentItem);
2707
+ } else {
2708
+ anchor.replaceChildren(currentItem);
2709
+ }
2710
+ }
2711
+ renderStream(anchor, stream) {
2712
+ const root = document.createElement("div");
2713
+ anchor.replaceChildren(root);
2714
+ const osc = new OSC(root);
2715
+ this.activeStreamSubscription = stream.subscribe((jsx2) => {
2716
+ const action = jsx2.action || "insert";
2717
+ if (action === "insert") {
2718
+ osc.handleInsert(jsx2);
2719
+ } else if (action === "update") {
2720
+ osc.handleUpdate(jsx2);
2721
+ } else {
2722
+ console.warn(`Unknown action: ${action}`);
2723
+ }
2724
+ }, (error) => {
2725
+ console.error("Stream error:", error);
2726
+ }, () => {
2727
+ const resolvedElement = osc.tree.dom;
2728
+ this.navigate.resolveStream(this.navigate.cursor, resolvedElement);
2729
+ this.activeStreamSubscription = null;
2730
+ });
2731
+ }
2732
+ isObservable(obj) {
2733
+ return obj && typeof obj.subscribe === "function";
2734
+ }
2735
+ };
2736
+ RouterOutlet = __decorate4([
2737
+ Component(),
2738
+ __metadata3("design:paramtypes", [typeof (_a = typeof Navigate !== "undefined" && Navigate) === "function" ? _a : Object])
2739
+ ], RouterOutlet);
2740
+
2741
+ // src/browser/modules/router_module/module.ts
2742
+ var RouterModule = class _RouterModule {
2743
+ static forRoot() {
2744
+ return {
2745
+ module: _RouterModule,
2746
+ declarations: [RouterOutlet],
2747
+ providers: [Navigate],
2748
+ exports: [Navigate, RouterOutlet]
2749
+ };
2750
+ }
2751
+ };
2752
+
2042
2753
  // src/browser/factory.ts
2043
- var BrowserFactory = class {
2044
- static create(rootModule, rootElement) {
2045
- const compiler = new Compiler();
2046
- const appNode = compiler.compile(rootModule);
2047
- const validation = compiler.validate(appNode);
2754
+ var CompilationService = class {
2755
+ constructor() {
2756
+ this.compiler = new Compiler();
2757
+ }
2758
+ compileAndValidate(rootModule) {
2759
+ const appNode = this.compiler.compile(rootModule);
2760
+ const validation = this.compiler.validate(appNode);
2048
2761
  if (!validation.valid) {
2049
- throw new Error(
2050
- "\u274C Validation failed:\n" + validation.errors.join("\n\n")
2051
- );
2762
+ throw new Error("Validation failed:\n" + validation.errors.join("\n\n"));
2052
2763
  }
2764
+ return appNode;
2765
+ }
2766
+ };
2767
+ var InjectorConfigurationService = class {
2768
+ static createRootInjector(appNode) {
2053
2769
  const allProviders = collectAllProvidersFromNode(appNode);
2054
- const rootInjector = new Injector([
2770
+ return new Injector([
2055
2771
  ...allProviders,
2056
2772
  {
2057
2773
  provide: "OSC_URL",
2058
2774
  useValue: "/osc"
2775
+ },
2776
+ {
2777
+ provide: Actor,
2778
+ useClass: Actor,
2779
+ eager: true
2780
+ },
2781
+ {
2782
+ provide: HttpClient,
2783
+ useClass: HttpClient
2059
2784
  }
2060
2785
  ]);
2061
- setCurrentInjector(rootInjector);
2786
+ }
2787
+ static instantiateEagerProviders(appNode, injector) {
2062
2788
  appNode.traverse((node) => {
2063
2789
  const providers = [...node.getProviders().values()];
2064
- providers.filter((provider) => provider.eager).forEach((p) => rootInjector.resolve(p.provide));
2790
+ providers.filter((provider) => provider.eager).forEach((p) => injector.resolve(p.provide));
2065
2791
  });
2792
+ }
2793
+ };
2794
+ var BootstrapService = class {
2795
+ static getBootstrapComponent(rootModule) {
2066
2796
  const bootstrap = Reflect.getMetadata(BOOTSTRAP, rootModule);
2067
- const instance = rootInjector.resolve(bootstrap);
2068
- instance.__injector = rootInjector;
2797
+ if (!bootstrap) {
2798
+ throw new Error(`No bootstrap component found. Ensure the root module has a @Bootstrap() decorator.`);
2799
+ }
2800
+ return bootstrap;
2801
+ }
2802
+ static renderBootstrap(bootstrap, injector, rootElement) {
2803
+ const instance = injector.resolve(bootstrap);
2804
+ instance.__injector = injector;
2069
2805
  const childDom = instance.build();
2070
2806
  rootElement.appendChild(childDom);
2071
2807
  }
2072
2808
  };
2809
+ var BrowserFactory = class {
2810
+ /**
2811
+ * Creates and bootstraps the application in the browser
2812
+ *
2813
+ * @param rootModule - The root module of the application
2814
+ * @param rootElement - The DOM element to mount the application to
2815
+ * @throws {Error} If validation fails or bootstrap component is not found
2816
+ */
2817
+ static create(rootModule, rootElement) {
2818
+ const compilationService = new CompilationService();
2819
+ const appNode = compilationService.compileAndValidate(rootModule);
2820
+ const rootInjector = InjectorConfigurationService.createRootInjector(appNode);
2821
+ setCurrentInjector(rootInjector);
2822
+ InjectorConfigurationService.instantiateEagerProviders(appNode, rootInjector);
2823
+ const bootstrap = BootstrapService.getBootstrapComponent(rootModule);
2824
+ BootstrapService.renderBootstrap(bootstrap, rootInjector, rootElement);
2825
+ }
2826
+ };
2073
2827
 
2074
2828
  // src/browser/dom/dom.ts
2075
2829
  var elementEffects = /* @__PURE__ */ new WeakMap();
@@ -2165,12 +2919,6 @@ var kithinjiorca = (() => {
2165
2919
  attach(value.value);
2166
2920
  });
2167
2921
  registerEffect(parent, cleanup);
2168
- } else if (isObservable(value)) {
2169
- const obs = value;
2170
- const subst = obs.subscribe((val) => {
2171
- attach(val);
2172
- });
2173
- registerEffect(parent, () => subst.unsubscribe());
2174
2922
  } else if (typeof value == "function") {
2175
2923
  const cleanup = effect(() => {
2176
2924
  attach(value());
@@ -2207,21 +2955,30 @@ var kithinjiorca = (() => {
2207
2955
  try {
2208
2956
  instance = injector.resolve(ComponentClass);
2209
2957
  } catch (e) {
2210
- throw new Error(e.message);
2958
+ console.log(e);
2959
+ throw new Error(`Failed to resolve component ${ComponentClass.name}: ${e.message}`);
2211
2960
  }
2212
2961
  const localProviders = Reflect.getMetadata(COMPONENT_PROVIDERS, ComponentClass) || [];
2213
2962
  if (localProviders.length > 0) {
2214
- injector = new Injector(localProviders.map((p) => ProviderNormalizer.normalize(p)), parentComponent.__injector);
2963
+ injector = new Injector(localProviders.map((p) => ProviderNormalizer.normalize(p)), parentComponent.__injector || injector);
2215
2964
  instance.__injector = injector;
2965
+ } else {
2966
+ instance.__injector = injector;
2967
+ }
2968
+ const routePattern = Reflect.getMetadata(COMPONENT_ROUTE, ComponentClass);
2969
+ let builtRoute = null;
2970
+ if (routePattern) {
2971
+ builtRoute = buildRouteFromProps(routePattern, props, ComponentClass.name);
2216
2972
  }
2217
2973
  instance.props = props;
2218
2974
  const root = instance.build();
2219
2975
  if (!(root instanceof Node)) {
2220
- throw new Error("Root is not instance of node");
2976
+ throw new Error(`Component ${ComponentClass.name}.build() must return a DOM Node`);
2221
2977
  }
2978
+ root.__route = builtRoute;
2222
2979
  const cleanup = () => {
2223
2980
  instance.__cleanup?.forEach((cb) => cb());
2224
- instance.onDestory?.();
2981
+ instance.onDestroy?.();
2225
2982
  };
2226
2983
  if (root.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
2227
2984
  const firstChild = root.firstChild;
@@ -2233,6 +2990,41 @@ var kithinjiorca = (() => {
2233
2990
  }
2234
2991
  return root;
2235
2992
  }
2993
+ function buildRouteFromProps(routePattern, props, componentName) {
2994
+ const [pathPattern, queryPattern] = routePattern.split("?");
2995
+ let path = pathPattern;
2996
+ const pathParams = pathPattern.match(/:(\w+)/g);
2997
+ if (pathParams) {
2998
+ for (const param of pathParams) {
2999
+ const paramName = param.slice(1);
3000
+ const paramValue = props[paramName];
3001
+ if (paramValue === void 0 || paramValue === null) {
3002
+ throw new Error(`Missing required prop "${paramName}" for route parameter in component ${componentName}. Route pattern: "${routePattern}"`);
3003
+ }
3004
+ path = path.replace(param, encodeURIComponent(String(paramValue)));
3005
+ }
3006
+ }
3007
+ if (queryPattern) {
3008
+ const queryParams = queryPattern.split("&").filter(Boolean);
3009
+ const queryParts = [];
3010
+ for (const param of queryParams) {
3011
+ const isOptional = param.endsWith("*");
3012
+ const paramName = isOptional ? param.slice(0, -1) : param;
3013
+ const paramValue = props[paramName];
3014
+ if (paramValue === void 0 || paramValue === null) {
3015
+ if (!isOptional) {
3016
+ throw new Error(`Missing required prop "${paramName}" for query parameter in component ${componentName}. Route pattern: "${routePattern}"`);
3017
+ }
3018
+ continue;
3019
+ }
3020
+ queryParts.push(`${encodeURIComponent(paramName)}=${encodeURIComponent(String(paramValue))}`);
3021
+ }
3022
+ if (queryParts.length > 0) {
3023
+ path += "?" + queryParts.join("&");
3024
+ }
3025
+ }
3026
+ return path;
3027
+ }
2236
3028
  function style(el, styleObj) {
2237
3029
  if (typeof styleObj === "function") {
2238
3030
  const cleanup = effect(() => {