@hypen-space/core 0.4.82 → 0.4.83

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.
@@ -262,6 +262,53 @@ class DataSourceManager {
262
262
  }
263
263
  }
264
264
 
265
+ // src/portable.ts
266
+ function notInstalled(name) {
267
+ throw new Error(`[@hypen-space/core] Portable helper "${name}" called before the engine was installed. ` + `Import @hypen-space/server, @hypen-space/web-engine, or call setPortableImpl() before use.`);
268
+ }
269
+ var current = {
270
+ diffState: () => notInstalled("diffState"),
271
+ matchPath: () => notInstalled("matchPath"),
272
+ pathGet: () => notInstalled("pathGet"),
273
+ pathHas: () => notInstalled("pathHas"),
274
+ pathSet: () => notInstalled("pathSet"),
275
+ pathDelete: () => notInstalled("pathDelete"),
276
+ encodeUriComponent: () => notInstalled("encodeUriComponent"),
277
+ decodeUriComponent: () => notInstalled("decodeUriComponent"),
278
+ parseQuery: () => notInstalled("parseQuery"),
279
+ buildUrl: () => notInstalled("buildUrl")
280
+ };
281
+ function setPortableImpl(impl) {
282
+ if (impl === null) {
283
+ current = {
284
+ diffState: () => notInstalled("diffState"),
285
+ matchPath: () => notInstalled("matchPath"),
286
+ pathGet: () => notInstalled("pathGet"),
287
+ pathHas: () => notInstalled("pathHas"),
288
+ pathSet: () => notInstalled("pathSet"),
289
+ pathDelete: () => notInstalled("pathDelete"),
290
+ encodeUriComponent: () => notInstalled("encodeUriComponent"),
291
+ decodeUriComponent: () => notInstalled("decodeUriComponent"),
292
+ parseQuery: () => notInstalled("parseQuery"),
293
+ buildUrl: () => notInstalled("buildUrl")
294
+ };
295
+ return;
296
+ }
297
+ current = impl;
298
+ }
299
+ var portable = {
300
+ diffState: (o, n, b) => current.diffState(o, n, b),
301
+ matchPath: (p, path) => current.matchPath(p, path),
302
+ pathGet: (v, p) => current.pathGet(v, p),
303
+ pathHas: (v, p) => current.pathHas(v, p),
304
+ pathSet: (v, p, nv) => current.pathSet(v, p, nv),
305
+ pathDelete: (v, p) => current.pathDelete(v, p),
306
+ encodeUriComponent: (s) => current.encodeUriComponent(s),
307
+ decodeUriComponent: (s) => current.decodeUriComponent(s),
308
+ parseQuery: (f) => current.parseQuery(f),
309
+ buildUrl: (p, q) => current.buildUrl(p, q)
310
+ };
311
+
265
312
  // src/state.ts
266
313
  var IS_PROXY = Symbol.for("hypen.isProxy");
267
314
  var RAW_TARGET = Symbol.for("hypen.rawTarget");
@@ -321,51 +368,7 @@ function deepClone(obj) {
321
368
  return cloneInternal(obj);
322
369
  }
323
370
  function diffState(oldState, newState, basePath = "") {
324
- const paths = [];
325
- const newValues = {};
326
- function diff(oldVal, newVal, path) {
327
- if (oldVal === newVal)
328
- return;
329
- if (typeof oldVal !== "object" || typeof newVal !== "object" || oldVal === null || newVal === null) {
330
- if (oldVal !== newVal) {
331
- paths.push(path);
332
- newValues[path] = newVal;
333
- }
334
- return;
335
- }
336
- if (Array.isArray(oldVal) || Array.isArray(newVal)) {
337
- if (!Array.isArray(oldVal) || !Array.isArray(newVal) || oldVal.length !== newVal.length) {
338
- paths.push(path);
339
- newValues[path] = newVal;
340
- return;
341
- }
342
- for (let i = 0;i < newVal.length; i++) {
343
- const itemPath = path ? `${path}.${i}` : `${i}`;
344
- diff(oldVal[i], newVal[i], itemPath);
345
- }
346
- return;
347
- }
348
- const oldKeys = new Set(Object.keys(oldVal));
349
- const newKeys = new Set(Object.keys(newVal));
350
- for (const key of newKeys) {
351
- const propPath = path ? `${path}.${key}` : key;
352
- if (!oldKeys.has(key)) {
353
- paths.push(propPath);
354
- newValues[propPath] = newVal[key];
355
- } else {
356
- diff(oldVal[key], newVal[key], propPath);
357
- }
358
- }
359
- for (const key of oldKeys) {
360
- if (!newKeys.has(key)) {
361
- const propPath = path ? `${path}.${key}` : key;
362
- paths.push(propPath);
363
- newValues[propPath] = undefined;
364
- }
365
- }
366
- }
367
- diff(oldState, newState, basePath);
368
- return { paths, newValues };
371
+ return portable.diffState(oldState, newState, basePath);
369
372
  }
370
373
  function createObservableState(initialState, options) {
371
374
  const opts = options || { onChange: () => {} };
@@ -714,6 +717,8 @@ class HypenAppBuilder {
714
717
  initialState;
715
718
  options;
716
719
  createdHandler;
720
+ activatedHandler;
721
+ deactivatedHandler;
717
722
  actionHandlers = new Map;
718
723
  destroyedHandler;
719
724
  disconnectHandler;
@@ -737,6 +742,14 @@ class HypenAppBuilder {
737
742
  this.actionHandlers.set(name, fn);
738
743
  return this;
739
744
  }
745
+ onActivated(fn) {
746
+ this.activatedHandler = fn;
747
+ return this;
748
+ }
749
+ onDeactivated(fn) {
750
+ this.deactivatedHandler = fn;
751
+ return this;
752
+ }
740
753
  onDestroyed(fn) {
741
754
  this.destroyedHandler = fn;
742
755
  return this;
@@ -788,6 +801,8 @@ class HypenAppBuilder {
788
801
  stateStore: this._stateStore,
789
802
  handlers: {
790
803
  onCreated: this.createdHandler,
804
+ onActivated: this.activatedHandler,
805
+ onDeactivated: this.deactivatedHandler,
791
806
  onAction: this.actionHandlers,
792
807
  onDestroyed: this.destroyedHandler,
793
808
  onDisconnect: this.disconnectHandler,
@@ -845,6 +860,7 @@ class HypenModuleInstance {
845
860
  definition;
846
861
  state;
847
862
  isDestroyed = false;
863
+ isActive = false;
848
864
  router;
849
865
  globalContext;
850
866
  stateChangeCallbacks = [];
@@ -924,6 +940,43 @@ class HypenModuleInstance {
924
940
  async waitForReady() {
925
941
  await this._readyPromise;
926
942
  }
943
+ async activate() {
944
+ if (this.isDestroyed || this.isActive)
945
+ return;
946
+ await this._readyPromise;
947
+ if (this.isDestroyed || this.isActive)
948
+ return;
949
+ this.isActive = true;
950
+ if (this.definition.handlers.onActivated) {
951
+ const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
952
+ try {
953
+ await this.definition.handlers.onActivated(this.state, context);
954
+ } catch (e) {
955
+ const error = e instanceof HypenError ? e : new ActionError("onActivated", e);
956
+ const shouldRethrow = await this.handleError(error, { lifecycle: "activated" });
957
+ if (shouldRethrow) {
958
+ throw error;
959
+ }
960
+ }
961
+ }
962
+ }
963
+ async deactivate() {
964
+ if (this.isDestroyed || !this.isActive)
965
+ return;
966
+ this.isActive = false;
967
+ if (this.definition.handlers.onDeactivated) {
968
+ const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
969
+ try {
970
+ await this.definition.handlers.onDeactivated(this.state, context);
971
+ } catch (e) {
972
+ const error = e instanceof HypenError ? e : new ActionError("onDeactivated", e);
973
+ const shouldRethrow = await this.handleError(error, { lifecycle: "deactivated" });
974
+ if (shouldRethrow) {
975
+ throw error;
976
+ }
977
+ }
978
+ }
979
+ }
927
980
  createGlobalContextAPI() {
928
981
  if (!this.globalContext) {
929
982
  throw new Error("Global context not available");
@@ -1072,6 +1125,9 @@ class HypenModuleInstance {
1072
1125
  async destroy() {
1073
1126
  if (this.isDestroyed)
1074
1127
  return;
1128
+ if (this.isActive) {
1129
+ await this.deactivate();
1130
+ }
1075
1131
  if (this.currentPersistKey && this.stateStore) {
1076
1132
  clearTimeout(this.persistDebounceTimer);
1077
1133
  const snapshot = getStateSnapshot(this.state);
@@ -1194,4 +1250,4 @@ export {
1194
1250
  Link
1195
1251
  };
1196
1252
 
1197
- //# debugId=E90E0FD4C65A409A64756E2164756E21
1253
+ //# debugId=70954EAAD4660C0764756E2164756E21