chayns-api 3.0.1 → 3.1.0-beta.1

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 (142) hide show
  1. package/dist/cjs/calls/index.js +4 -1
  2. package/dist/cjs/calls/visibilityChangeListener.js +4 -4
  3. package/dist/cjs/components/ChaynsProvider.js +34 -6
  4. package/dist/cjs/components/withHydrationBoundary.js +2 -2
  5. package/dist/cjs/constants/index.js +0 -22
  6. package/dist/cjs/contexts/HistoryLayerContext.js +89 -0
  7. package/dist/cjs/contexts/index.js +38 -0
  8. package/dist/cjs/handler/history/FrameHistoryLayer.js +100 -0
  9. package/dist/cjs/handler/history/HistoryLayer.js +321 -0
  10. package/dist/cjs/handler/history/index.js +19 -0
  11. package/dist/cjs/hooks/history.js +454 -0
  12. package/dist/cjs/hooks/index.js +62 -1
  13. package/dist/cjs/host/ChaynsHost.js +113 -54
  14. package/dist/cjs/host/iframe/HostIframe.js +70 -5
  15. package/dist/cjs/host/module/ModuleHost.js +50 -44
  16. package/dist/cjs/index.js +139 -6
  17. package/dist/cjs/types/history.js +1 -0
  18. package/dist/cjs/umd.index.js +2 -2
  19. package/dist/cjs/utils/EventBus.js +33 -0
  20. package/dist/cjs/{util → utils}/appStorage.js +2 -2
  21. package/dist/cjs/utils/equality.js +19 -0
  22. package/dist/cjs/utils/history/BlockRegistry.js +153 -0
  23. package/dist/cjs/utils/history/NavigationQueue.js +389 -0
  24. package/dist/cjs/utils/history/layerTree.js +32 -0
  25. package/dist/cjs/utils/history/nativeBackHandling.js +61 -0
  26. package/dist/cjs/utils/history/navigationIndex.js +74 -0
  27. package/dist/cjs/utils/history/rootLayer.js +213 -0
  28. package/dist/cjs/utils/history/segments.js +15 -0
  29. package/dist/cjs/utils/history/stateProjector.js +156 -0
  30. package/dist/cjs/utils/history/url.js +47 -0
  31. package/dist/cjs/utils/history/window.js +9 -0
  32. package/dist/cjs/wrapper/AppWrapper.js +24 -24
  33. package/dist/cjs/wrapper/FrameWrapper.js +35 -2
  34. package/dist/cjs/wrapper/ModuleFederationWrapper.js +2 -0
  35. package/dist/cjs/wrapper/StaticChaynsApi.js +1 -1
  36. package/dist/esm/calls/index.js +2 -0
  37. package/dist/esm/calls/visibilityChangeListener.js +1 -1
  38. package/dist/esm/components/ChaynsProvider.js +34 -6
  39. package/dist/esm/components/withHydrationBoundary.js +1 -1
  40. package/dist/esm/constants/index.js +1 -3
  41. package/dist/esm/contexts/HistoryLayerContext.js +76 -0
  42. package/dist/esm/contexts/index.js +3 -0
  43. package/dist/esm/handler/history/FrameHistoryLayer.js +105 -0
  44. package/dist/esm/handler/history/HistoryLayer.js +321 -0
  45. package/dist/esm/handler/history/index.js +2 -0
  46. package/dist/esm/hooks/history.js +428 -0
  47. package/dist/esm/hooks/index.js +2 -1
  48. package/dist/esm/host/ChaynsHost.js +113 -54
  49. package/dist/esm/host/iframe/HostIframe.js +70 -5
  50. package/dist/esm/host/module/ModuleHost.js +50 -44
  51. package/dist/esm/index.js +15 -6
  52. package/dist/esm/types/history.js +1 -0
  53. package/dist/esm/umd.index.js +2 -2
  54. package/dist/esm/utils/EventBus.js +31 -0
  55. package/dist/esm/{util → utils}/appStorage.js +1 -1
  56. package/dist/esm/utils/equality.js +12 -0
  57. package/dist/esm/utils/history/BlockRegistry.js +151 -0
  58. package/dist/esm/utils/history/NavigationQueue.js +386 -0
  59. package/dist/esm/utils/history/layerTree.js +24 -0
  60. package/dist/esm/utils/history/nativeBackHandling.js +59 -0
  61. package/dist/esm/utils/history/navigationIndex.js +62 -0
  62. package/dist/esm/utils/history/rootLayer.js +205 -0
  63. package/dist/esm/utils/history/segments.js +7 -0
  64. package/dist/esm/utils/history/stateProjector.js +147 -0
  65. package/dist/esm/utils/history/url.js +40 -0
  66. package/dist/esm/utils/history/window.js +3 -0
  67. package/dist/esm/wrapper/AppWrapper.js +6 -6
  68. package/dist/esm/wrapper/FrameWrapper.js +35 -2
  69. package/dist/esm/wrapper/ModuleFederationWrapper.js +2 -0
  70. package/dist/esm/wrapper/StaticChaynsApi.js +2 -1
  71. package/dist/types/calls/index.d.ts +5 -0
  72. package/dist/types/components/ChaynsProvider.d.ts +21 -0
  73. package/dist/types/constants/index.d.ts +0 -2
  74. package/dist/types/contexts/HistoryLayerContext.d.ts +33 -0
  75. package/dist/types/contexts/index.d.ts +3 -0
  76. package/dist/types/handler/history/FrameHistoryLayer.d.ts +99 -0
  77. package/dist/types/handler/history/HistoryLayer.d.ts +117 -0
  78. package/dist/types/handler/history/index.d.ts +2 -0
  79. package/dist/types/hooks/history.d.ts +89 -0
  80. package/dist/types/hooks/index.d.ts +1 -0
  81. package/dist/types/host/ChaynsHost.d.ts +12 -0
  82. package/dist/types/host/iframe/HostIframe.d.ts +4 -0
  83. package/dist/types/host/module/ModuleHost.d.ts +4 -0
  84. package/dist/types/index.d.ts +15 -6
  85. package/dist/types/types/IChaynsReact.d.ts +3 -0
  86. package/dist/types/types/history.d.ts +74 -0
  87. package/dist/types/umd.index.d.ts +2 -2
  88. package/dist/types/utils/EventBus.d.ts +10 -0
  89. package/dist/types/{util → utils}/collectCssChunks.d.ts +1 -1
  90. package/dist/types/utils/equality.d.ts +2 -0
  91. package/dist/types/utils/history/BlockRegistry.d.ts +45 -0
  92. package/dist/types/utils/history/NavigationQueue.d.ts +118 -0
  93. package/dist/types/utils/history/layerTree.d.ts +10 -0
  94. package/dist/types/utils/history/nativeBackHandling.d.ts +47 -0
  95. package/dist/types/utils/history/navigationIndex.d.ts +17 -0
  96. package/dist/types/utils/history/rootLayer.d.ts +42 -0
  97. package/dist/types/utils/history/segments.d.ts +2 -0
  98. package/dist/types/utils/history/stateProjector.d.ts +24 -0
  99. package/dist/types/utils/history/url.d.ts +17 -0
  100. package/dist/types/utils/history/window.d.ts +1 -0
  101. package/dist/types/wrapper/FrameWrapper.d.ts +1 -0
  102. package/dist/types/wrapper/StaticChaynsApi.d.ts +1 -0
  103. package/package.json +2 -1
  104. /package/dist/cjs/{constants → contexts}/hydrationContext.js +0 -0
  105. /package/dist/cjs/{constants → contexts}/moduleContext.js +0 -0
  106. /package/dist/cjs/{helper/apiListenerHelper.js → utils/apiListener.js} +0 -0
  107. /package/dist/cjs/{util → utils}/appCall.js +0 -0
  108. /package/dist/cjs/{util → utils}/bindChaynsApi.js +0 -0
  109. /package/dist/cjs/{util → utils}/collectCssChunks.js +0 -0
  110. /package/dist/cjs/{util → utils}/deviceHelper.js +0 -0
  111. /package/dist/cjs/{util → utils}/heightHelper.js +0 -0
  112. /package/dist/cjs/{util → utils}/initModuleFederationSharing.js +0 -0
  113. /package/dist/cjs/{util → utils}/is.js +0 -0
  114. /package/dist/cjs/{util → utils}/postIframeForm.js +0 -0
  115. /package/dist/cjs/{util → utils}/transferNestedFunctions.js +0 -0
  116. /package/dist/cjs/{util → utils}/url.js +0 -0
  117. /package/dist/esm/{constants → contexts}/hydrationContext.js +0 -0
  118. /package/dist/esm/{constants → contexts}/moduleContext.js +0 -0
  119. /package/dist/esm/{helper/apiListenerHelper.js → utils/apiListener.js} +0 -0
  120. /package/dist/esm/{util → utils}/appCall.js +0 -0
  121. /package/dist/esm/{util → utils}/bindChaynsApi.js +0 -0
  122. /package/dist/esm/{util → utils}/collectCssChunks.js +0 -0
  123. /package/dist/esm/{util → utils}/deviceHelper.js +0 -0
  124. /package/dist/esm/{util → utils}/heightHelper.js +0 -0
  125. /package/dist/esm/{util → utils}/initModuleFederationSharing.js +0 -0
  126. /package/dist/esm/{util → utils}/is.js +0 -0
  127. /package/dist/esm/{util → utils}/postIframeForm.js +0 -0
  128. /package/dist/esm/{util → utils}/transferNestedFunctions.js +0 -0
  129. /package/dist/esm/{util → utils}/url.js +0 -0
  130. /package/dist/types/{constants → contexts}/hydrationContext.d.ts +0 -0
  131. /package/dist/types/{constants → contexts}/moduleContext.d.ts +0 -0
  132. /package/dist/types/{helper/apiListenerHelper.d.ts → utils/apiListener.d.ts} +0 -0
  133. /package/dist/types/{util → utils}/appCall.d.ts +0 -0
  134. /package/dist/types/{util → utils}/appStorage.d.ts +0 -0
  135. /package/dist/types/{util → utils}/bindChaynsApi.d.ts +0 -0
  136. /package/dist/types/{util → utils}/deviceHelper.d.ts +0 -0
  137. /package/dist/types/{util → utils}/heightHelper.d.ts +0 -0
  138. /package/dist/types/{util → utils}/initModuleFederationSharing.d.ts +0 -0
  139. /package/dist/types/{util → utils}/is.d.ts +0 -0
  140. /package/dist/types/{util → utils}/postIframeForm.d.ts +0 -0
  141. /package/dist/types/{util → utils}/transferNestedFunctions.d.ts +0 -0
  142. /package/dist/types/{util → utils}/url.d.ts +0 -0
@@ -0,0 +1,386 @@
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
+ import { hasWindowHistory } from './window';
5
+ import { shallowEqualArr, shallowEqualObj } from '../equality';
6
+ export class NavigationQueue {
7
+ constructor(deps) {
8
+ _defineProperty(this, "queue", []);
9
+ _defineProperty(this, "isRunning", false);
10
+ _defineProperty(this, "deps", void 0);
11
+ this.deps = deps;
12
+ }
13
+ enqueue(op) {
14
+ return new Promise(resolve => {
15
+ this.queue.push({
16
+ op,
17
+ resolve
18
+ });
19
+ void this.tick();
20
+ });
21
+ }
22
+ async tick() {
23
+ if (this.isRunning) return;
24
+ this.isRunning = true;
25
+ try {
26
+ while (this.queue.length > 0) {
27
+ const entry = this.queue.shift();
28
+ try {
29
+ const result = await this.process(entry.op);
30
+ entry.resolve(result);
31
+ } catch (error) {
32
+ entry.resolve({
33
+ isOk: false,
34
+ reason: 'error',
35
+ error
36
+ });
37
+ }
38
+ }
39
+ } finally {
40
+ this.isRunning = false;
41
+ }
42
+ }
43
+ async process(op) {
44
+ switch (op.kind) {
45
+ case 'setRoute':
46
+ return this.processSetRoute(op);
47
+ case 'setState':
48
+ return this.processSetState(op);
49
+ case 'setParams':
50
+ return this.processSetParams(op);
51
+ case 'setHash':
52
+ return this.processSetHash(op);
53
+ case 'setActiveChild':
54
+ return this.processSetActiveChild(op);
55
+ case 'navigate':
56
+ return this.processNavigate(op);
57
+ case 'popstate':
58
+ return this.processPopstate(op);
59
+ default:
60
+ {
61
+ return {
62
+ isOk: false,
63
+ reason: 'error',
64
+ error: new Error('Unknown op')
65
+ };
66
+ }
67
+ }
68
+ }
69
+ async processSetRoute(op) {
70
+ const layer = this.resolveActiveLayer(op.layerId);
71
+ if (!layer) return {
72
+ isOk: false,
73
+ reason: 'stale'
74
+ };
75
+ const allowed = await this.deps.checkBlocks(layer);
76
+ if (!allowed) return {
77
+ isOk: false,
78
+ reason: 'blocked'
79
+ };
80
+ const prevSegments = layer._getOwnSegments();
81
+ const prevParams = layer._getOwnParams();
82
+ const prevHash = layer._getOwnHash();
83
+ layer._setOwnSegmentsSilent(op.segments);
84
+ if (op.opts.params !== undefined) layer._setOwnParamsSilent(op.opts.params);
85
+ if (op.opts.hash !== undefined) layer._setOwnHashSilent(op.opts.hash);
86
+ const changed = op._notifyEvenIfUnchanged === true || !shallowEqualArr(prevSegments, op.segments) || op.opts.params !== undefined && !shallowEqualObj(prevParams, op.opts.params) || op.opts.hash !== undefined && prevHash !== op.opts.hash;
87
+ if (changed) {
88
+ if (op._skipCommit !== true) {
89
+ this.commit(op.opts.isReplace === true);
90
+ }
91
+ layer._emit('change');
92
+ }
93
+ return {
94
+ isOk: true
95
+ };
96
+ }
97
+ async processSetParams(op) {
98
+ const layer = this.resolveActiveLayer(op.layerId);
99
+ if (!layer) return {
100
+ isOk: false,
101
+ reason: 'stale'
102
+ };
103
+ const allowed = await this.deps.checkBlocks(layer);
104
+ if (!allowed) return {
105
+ isOk: false,
106
+ reason: 'blocked'
107
+ };
108
+ const prev = layer._getOwnParams();
109
+ layer._setOwnParamsSilent(op.params);
110
+ if (!shallowEqualObj(prev, op.params)) {
111
+ this.commit(op.opts.isReplace === true);
112
+ layer._emit('change');
113
+ }
114
+ return {
115
+ isOk: true
116
+ };
117
+ }
118
+ async processSetHash(op) {
119
+ const layer = this.resolveActiveLayer(op.layerId);
120
+ if (!layer) return {
121
+ isOk: false,
122
+ reason: 'stale'
123
+ };
124
+ const allowed = await this.deps.checkBlocks(layer);
125
+ if (!allowed) return {
126
+ isOk: false,
127
+ reason: 'blocked'
128
+ };
129
+ const prev = layer._getOwnHash();
130
+ layer._setOwnHashSilent(op.hash);
131
+ if (prev !== op.hash) {
132
+ this.commit(op.opts.isReplace === true);
133
+ layer._emit('change');
134
+ }
135
+ return {
136
+ isOk: true
137
+ };
138
+ }
139
+ async processSetState(op) {
140
+ const layer = this.resolveActiveLayer(op.layerId);
141
+ if (!layer) return {
142
+ isOk: false,
143
+ reason: 'stale'
144
+ };
145
+ const allowed = await this.deps.checkBlocks(layer);
146
+ if (!allowed) return {
147
+ isOk: false,
148
+ reason: 'blocked'
149
+ };
150
+ const previous = layer._getOwnState();
151
+ layer._setOwnStateSilent(op.state);
152
+ const changed = !shallowEqualObj(previous, op.state);
153
+ if (changed) {
154
+ this.commit(op.opts.isReplace === true);
155
+ layer._emit('change');
156
+ }
157
+ return {
158
+ isOk: true
159
+ };
160
+ }
161
+ async processSetActiveChild(op) {
162
+ const layer = this.resolveActiveLayer(op.layerId);
163
+ if (!layer) return {
164
+ isOk: false,
165
+ reason: 'stale'
166
+ };
167
+ const allowed = await this.deps.checkBlocks(layer);
168
+ if (!allowed) return {
169
+ isOk: false,
170
+ reason: 'blocked'
171
+ };
172
+ const previousUrl = this.deps.projectUrl();
173
+ const previousId = layer.getActiveChildId();
174
+ if (op.childId !== null && !layer.getChildLayer(op.childId)) {
175
+ layer.createChildLayer(op.childId);
176
+ }
177
+ layer._setActiveChildSilent(op.childId);
178
+ let childDataChanged = false;
179
+ if (op.childId && op.init) {
180
+ const child = layer.getChildLayer(op.childId);
181
+ if (child) {
182
+ if (op.init.route) {
183
+ child._setOwnSegmentsSilent(op.init.route);
184
+ childDataChanged = true;
185
+ }
186
+ if (op.init.state) {
187
+ child._setOwnStateSilent(op.init.state);
188
+ childDataChanged = true;
189
+ }
190
+ }
191
+ }
192
+ if (op.childId) {
193
+ const child = layer.getChildLayer(op.childId);
194
+ if (child && child._getOwnSegments().length === 0 && child.getSegmentCount() > 0) {
195
+ const root = this.deps.getRoot();
196
+ const bootstrapSegs = root._consumeBootstrapSegments(child.getSegmentCount());
197
+ if (bootstrapSegs) {
198
+ child._setOwnSegmentsSilent(bootstrapSegs);
199
+ childDataChanged = true;
200
+ }
201
+ }
202
+ }
203
+ if (previousId !== op.childId) {
204
+ const nextUrl = this.deps.projectUrl();
205
+ const shouldReplace = previousUrl === nextUrl;
206
+ this.commit(shouldReplace);
207
+ layer._emit('change');
208
+ }
209
+ if (childDataChanged && op.childId) {
210
+ const child = layer.getChildLayer(op.childId);
211
+ if (child) child._emit('change');
212
+ }
213
+ return {
214
+ isOk: true
215
+ };
216
+ }
217
+ async processNavigate(op) {
218
+ const layer = this.resolveActiveLayer(op.layerId);
219
+ if (!layer) return {
220
+ isOk: false,
221
+ reason: 'stale'
222
+ };
223
+ const allowed = await this.deps.checkBlocks(layer);
224
+ if (!allowed) return {
225
+ isOk: false,
226
+ reason: 'blocked'
227
+ };
228
+ const prevSeg = layer._getOwnSegments();
229
+ const prevState = layer._getOwnState();
230
+ const prevParams = layer._getOwnParams();
231
+ const prevHash = layer._getOwnHash();
232
+ const prevActiveChild = layer.getActiveChildId();
233
+ if (op.route) layer._setOwnSegmentsSilent(op.route);
234
+ if (op.state) layer._setOwnStateSilent(op.state);
235
+ if (op.params !== undefined) layer._setOwnParamsSilent(op.params);
236
+ if (op.hash !== undefined) layer._setOwnHashSilent(op.hash);
237
+ const segChanged = op.route ? !shallowEqualArr(prevSeg, op.route) : false;
238
+ const stateChanged = op.state ? !shallowEqualObj(prevState, op.state) : false;
239
+ const paramsChanged = op.params !== undefined ? !shallowEqualObj(prevParams, op.params) : false;
240
+ const hashChanged = op.hash !== undefined ? prevHash !== op.hash : false;
241
+ let activeChildChanged = false;
242
+ let childDataChanged = false;
243
+ if (op.activeChild !== undefined) {
244
+ if (op.activeChild !== null && !layer.getChildLayer(op.activeChild)) {
245
+ layer.createChildLayer(op.activeChild);
246
+ }
247
+ layer._setActiveChildSilent(op.activeChild);
248
+ activeChildChanged = prevActiveChild !== op.activeChild;
249
+ if (op.activeChild && op.activeChildInit) {
250
+ const child = layer.getChildLayer(op.activeChild);
251
+ if (child) {
252
+ if (op.activeChildInit.route) {
253
+ child._setOwnSegmentsSilent(op.activeChildInit.route);
254
+ childDataChanged = true;
255
+ }
256
+ if (op.activeChildInit.state) {
257
+ child._setOwnStateSilent(op.activeChildInit.state);
258
+ childDataChanged = true;
259
+ }
260
+ }
261
+ }
262
+ if (op.activeChild) {
263
+ const child = layer.getChildLayer(op.activeChild);
264
+ if (child && child._getOwnSegments().length === 0 && child.getSegmentCount() > 0) {
265
+ const root = this.deps.getRoot();
266
+ const bootstrapSegs = root._consumeBootstrapSegments(child.getSegmentCount());
267
+ if (bootstrapSegs) {
268
+ child._setOwnSegmentsSilent(bootstrapSegs);
269
+ childDataChanged = true;
270
+ }
271
+ }
272
+ }
273
+ }
274
+ if (segChanged || stateChanged || paramsChanged || hashChanged || activeChildChanged) {
275
+ this.commit(op.opts.isReplace === true);
276
+ layer._emit('change');
277
+ }
278
+ if (childDataChanged && op.activeChild) {
279
+ const child = layer.getChildLayer(op.activeChild);
280
+ if (child) child._emit('change');
281
+ }
282
+ return {
283
+ isOk: true
284
+ };
285
+ }
286
+ async processPopstate(op) {
287
+ const {
288
+ changedLayerIds
289
+ } = this.deps.diffIncomingState(op.rawState);
290
+ const currentProjectedUrl = this.deps.projectUrl();
291
+ const browserPathname = hasWindowHistory() ? window.location.pathname : '';
292
+ if (browserPathname && browserPathname !== new URL(currentProjectedUrl, 'http://x').pathname) {
293
+ changedLayerIds.add(this.deps.getRoot().id);
294
+ }
295
+ const target = this.resolveLowestCommonLayer(changedLayerIds);
296
+ if (target && op.skipBlockCheck !== true) {
297
+ const allowed = await this.deps.checkBlocks(target);
298
+ if (!allowed) {
299
+ await this.deps.silentGo(+1);
300
+ return {
301
+ isOk: false,
302
+ reason: 'blocked'
303
+ };
304
+ }
305
+ }
306
+ const {
307
+ changedLayerIds: applied
308
+ } = this.deps.applyIncomingState(op.rawState);
309
+ const {
310
+ changedLayerIds: urlChanged
311
+ } = this.deps.applyUrlSegments();
312
+ const allChanged = new Set([...applied, ...urlChanged]);
313
+ for (const id of allChanged) {
314
+ const layer = this.deps.findLayer(id);
315
+ if (layer) layer._emit('popstate');
316
+ }
317
+ return {
318
+ isOk: true
319
+ };
320
+ }
321
+ resolveActiveLayer(id) {
322
+ const layer = this.deps.findLayer(id);
323
+ if (!layer) {
324
+ return undefined;
325
+ }
326
+ if (layer._isDestroyed()) {
327
+ return undefined;
328
+ }
329
+ if (!layer._isInActiveChain()) {
330
+ return undefined;
331
+ }
332
+ return layer;
333
+ }
334
+ resolveLowestCommonLayer(ids) {
335
+ if (ids.size === 0) return undefined;
336
+ const ancestorLists = [];
337
+ for (const id of ids) {
338
+ const layer = this.deps.findLayer(id);
339
+ if (!layer) continue;
340
+ const ancestors = [];
341
+ let node = layer;
342
+ while (node) {
343
+ var _node$parent;
344
+ ancestors.unshift(node);
345
+ node = (_node$parent = node.parent) !== null && _node$parent !== void 0 ? _node$parent : null;
346
+ }
347
+ ancestorLists.push(ancestors);
348
+ }
349
+ if (ancestorLists.length === 0) return undefined;
350
+ if (ancestorLists.length === 1) return ancestorLists[0][ancestorLists[0].length - 1];
351
+ let lca;
352
+ const minLen = Math.min(...ancestorLists.map(a => a.length));
353
+ for (let d = 0; d < minLen; d++) {
354
+ const candidate = ancestorLists[0][d];
355
+ if (ancestorLists.every(a => {
356
+ var _a$d;
357
+ return ((_a$d = a[d]) === null || _a$d === void 0 ? void 0 : _a$d.id) === candidate.id;
358
+ })) {
359
+ lca = candidate;
360
+ } else {
361
+ break;
362
+ }
363
+ }
364
+ return lca;
365
+ }
366
+ commit(isReplace) {
367
+ var _this$deps$onCommit, _this$deps;
368
+ if (!hasWindowHistory()) return;
369
+ const url = this.deps.projectUrl();
370
+ const state = this.deps.projectState();
371
+ const idx = isReplace ? this.deps.getCurrentIdx() : this.deps.incrementIdx();
372
+ const stateWithMeta = {
373
+ ...state,
374
+ __chaynsHistory: {
375
+ ...state.__chaynsHistory,
376
+ __idx: idx
377
+ }
378
+ };
379
+ if (isReplace) {
380
+ window.history.replaceState(stateWithMeta, '', url);
381
+ } else {
382
+ window.history.pushState(stateWithMeta, '', url);
383
+ }
384
+ (_this$deps$onCommit = (_this$deps = this.deps).onCommit) === null || _this$deps$onCommit === void 0 || _this$deps$onCommit.call(_this$deps);
385
+ }
386
+ }
@@ -0,0 +1,24 @@
1
+ export function getChaynsHistoryActiveChain(root) {
2
+ const chain = [root];
3
+ let current = root;
4
+ for (;;) {
5
+ const childId = current.getActiveChildId();
6
+ if (!childId) break;
7
+ const child = current.getChildLayer(childId);
8
+ if (!child) break;
9
+ chain.push(child);
10
+ current = child;
11
+ }
12
+ return chain;
13
+ }
14
+ export function findChaynsHistoryLayerById(root, id) {
15
+ if (root.id === id) return root;
16
+ for (const child of root._getChildren().values()) {
17
+ const found = findChaynsHistoryLayerById(child, id);
18
+ if (found) return found;
19
+ }
20
+ return undefined;
21
+ }
22
+ export function isInChaynsHistoryActiveChain(layer) {
23
+ return layer._isInActiveChain();
24
+ }
@@ -0,0 +1,59 @@
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
+ import { getDevice, invokeCall } from '../../calls';
5
+ import { AppFlavor } from '../../types/IChaynsReact';
6
+ import { getCurrentIdx } from './navigationIndex';
7
+ import { hasWindowHistory } from './window';
8
+ const DISABLE_SWIPE_BACK_GESTURE_ACTION = 249;
9
+ export class NativeBackHandler {
10
+ constructor(opts) {
11
+ _defineProperty(this, "opts", void 0);
12
+ _defineProperty(this, "isInterceptionEnabled", void 0);
13
+ _defineProperty(this, "bypassNextPopstateBlockCheck", false);
14
+ _defineProperty(this, "sync", () => {
15
+ if (!hasWindowHistory() || !NativeBackHandler.isSupported()) {
16
+ return;
17
+ }
18
+ const next = this.shouldEnableInterception();
19
+ if (this.isInterceptionEnabled === next) {
20
+ return;
21
+ }
22
+ void invokeCall({
23
+ action: DISABLE_SWIPE_BACK_GESTURE_ACTION,
24
+ value: {
25
+ enabled: next
26
+ }
27
+ }, next ? this.handleNativeBack : undefined);
28
+ this.isInterceptionEnabled = next;
29
+ });
30
+ _defineProperty(this, "handleNativeBack", () => {
31
+ void this.runNativeBack();
32
+ });
33
+ this.opts = opts;
34
+ }
35
+ consumeBypassFlag() {
36
+ if (!this.bypassNextPopstateBlockCheck) return false;
37
+ this.bypassNextPopstateBlockCheck = false;
38
+ return true;
39
+ }
40
+ static isSupported() {
41
+ try {
42
+ var _getDevice$app;
43
+ return ((_getDevice$app = getDevice().app) === null || _getDevice$app === void 0 ? void 0 : _getDevice$app.flavor) === AppFlavor.Chayns;
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+ shouldEnableInterception() {
49
+ return this.opts.blockRegistry.hasActiveBlocks(this.opts.rootLayer) || getCurrentIdx() > 0;
50
+ }
51
+ async runNativeBack() {
52
+ const isAllowed = await this.opts.blockRegistry.checkActiveBlocks(this.opts.rootLayer);
53
+ if (!isAllowed || !hasWindowHistory()) {
54
+ return;
55
+ }
56
+ this.bypassNextPopstateBlockCheck = true;
57
+ window.history.back();
58
+ }
59
+ }
@@ -0,0 +1,62 @@
1
+ import { hasWindowHistory } from './window';
2
+ const CHAYNS_HISTORY_STATE_KEY = '__chaynsHistory';
3
+ let currentIdx = 0;
4
+ let pendingSilentCount = 0;
5
+ let silentResolve = null;
6
+ export function incrementIdx() {
7
+ return ++currentIdx;
8
+ }
9
+ export function getCurrentIdx() {
10
+ return currentIdx;
11
+ }
12
+ export function setCurrentIdx(idx) {
13
+ if (!Number.isInteger(idx) || idx < 0) {
14
+ return;
15
+ }
16
+ currentIdx = idx;
17
+ }
18
+ export function extractHistoryIndex(raw) {
19
+ if (!raw || typeof raw !== 'object') {
20
+ return null;
21
+ }
22
+ const chaynsHistory = raw[CHAYNS_HISTORY_STATE_KEY];
23
+ if (!chaynsHistory || typeof chaynsHistory !== 'object') {
24
+ return null;
25
+ }
26
+ const idx = chaynsHistory.__idx;
27
+ if (typeof idx !== 'number' || !Number.isInteger(idx) || idx < 0) {
28
+ return null;
29
+ }
30
+ return idx;
31
+ }
32
+ export function syncCurrentIdxFromState(raw) {
33
+ const idx = extractHistoryIndex(raw);
34
+ if (idx === null) {
35
+ return null;
36
+ }
37
+ currentIdx = idx;
38
+ return idx;
39
+ }
40
+ export function silentGo(delta) {
41
+ if (!hasWindowHistory()) return Promise.resolve();
42
+ return new Promise(resolve => {
43
+ pendingSilentCount++;
44
+ window.history.go(delta);
45
+ const timeout = setTimeout(() => {
46
+ silentResolve = null;
47
+ resolve();
48
+ }, 2000);
49
+ silentResolve = () => {
50
+ clearTimeout(timeout);
51
+ resolve();
52
+ };
53
+ });
54
+ }
55
+ export function consumeSilent() {
56
+ if (pendingSilentCount <= 0) return false;
57
+ pendingSilentCount--;
58
+ const res = silentResolve;
59
+ silentResolve = null;
60
+ res === null || res === void 0 || res();
61
+ return true;
62
+ }