chayns-api 3.0.0 → 3.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/calls/index.js +4 -1
- package/dist/cjs/calls/visibilityChangeListener.js +4 -4
- package/dist/cjs/components/ChaynsProvider.js +34 -6
- package/dist/cjs/components/withHydrationBoundary.js +2 -2
- package/dist/cjs/constants/index.js +0 -22
- package/dist/cjs/contexts/HistoryLayerContext.js +89 -0
- package/dist/cjs/contexts/index.js +38 -0
- package/dist/cjs/handler/history/FrameHistoryLayer.js +100 -0
- package/dist/cjs/handler/history/HistoryLayer.js +321 -0
- package/dist/cjs/handler/history/index.js +19 -0
- package/dist/cjs/hooks/history.js +454 -0
- package/dist/cjs/hooks/index.js +62 -1
- package/dist/cjs/host/ChaynsHost.js +113 -54
- package/dist/cjs/host/iframe/HostIframe.js +70 -5
- package/dist/cjs/host/module/ModuleHost.js +50 -44
- package/dist/cjs/index.js +139 -6
- package/dist/cjs/types/history.js +1 -0
- package/dist/cjs/umd.index.js +2 -2
- package/dist/cjs/utils/EventBus.js +33 -0
- package/dist/cjs/{util → utils}/appStorage.js +2 -2
- package/dist/cjs/utils/equality.js +19 -0
- package/dist/cjs/utils/history/BlockRegistry.js +110 -0
- package/dist/cjs/utils/history/NavigationQueue.js +388 -0
- package/dist/cjs/utils/history/layerTree.js +32 -0
- package/dist/cjs/utils/history/navigationIndex.js +42 -0
- package/dist/cjs/utils/history/rootLayer.js +175 -0
- package/dist/cjs/utils/history/segments.js +15 -0
- package/dist/cjs/utils/history/stateProjector.js +156 -0
- package/dist/cjs/utils/history/url.js +47 -0
- package/dist/cjs/utils/history/window.js +9 -0
- package/dist/cjs/wrapper/AppWrapper.js +23 -23
- package/dist/cjs/wrapper/FrameWrapper.js +35 -2
- package/dist/cjs/wrapper/ModuleFederationWrapper.js +2 -0
- package/dist/cjs/wrapper/StaticChaynsApi.js +1 -1
- package/dist/esm/calls/index.js +2 -0
- package/dist/esm/calls/visibilityChangeListener.js +1 -1
- package/dist/esm/components/ChaynsProvider.js +34 -6
- package/dist/esm/components/withHydrationBoundary.js +1 -1
- package/dist/esm/constants/index.js +1 -3
- package/dist/esm/contexts/HistoryLayerContext.js +76 -0
- package/dist/esm/contexts/index.js +3 -0
- package/dist/esm/handler/history/FrameHistoryLayer.js +105 -0
- package/dist/esm/handler/history/HistoryLayer.js +321 -0
- package/dist/esm/handler/history/index.js +2 -0
- package/dist/esm/hooks/history.js +428 -0
- package/dist/esm/hooks/index.js +2 -1
- package/dist/esm/host/ChaynsHost.js +113 -54
- package/dist/esm/host/iframe/HostIframe.js +70 -5
- package/dist/esm/host/module/ModuleHost.js +50 -44
- package/dist/esm/index.js +15 -6
- package/dist/esm/types/history.js +1 -0
- package/dist/esm/umd.index.js +2 -2
- package/dist/esm/utils/EventBus.js +31 -0
- package/dist/esm/{util → utils}/appStorage.js +1 -1
- package/dist/esm/utils/equality.js +12 -0
- package/dist/esm/utils/history/BlockRegistry.js +108 -0
- package/dist/esm/utils/history/NavigationQueue.js +385 -0
- package/dist/esm/utils/history/layerTree.js +24 -0
- package/dist/esm/utils/history/navigationIndex.js +33 -0
- package/dist/esm/utils/history/rootLayer.js +167 -0
- package/dist/esm/utils/history/segments.js +7 -0
- package/dist/esm/utils/history/stateProjector.js +147 -0
- package/dist/esm/utils/history/url.js +40 -0
- package/dist/esm/utils/history/window.js +3 -0
- package/dist/esm/wrapper/AppWrapper.js +5 -5
- package/dist/esm/wrapper/FrameWrapper.js +35 -2
- package/dist/esm/wrapper/ModuleFederationWrapper.js +2 -0
- package/dist/esm/wrapper/StaticChaynsApi.js +2 -1
- package/dist/types/calls/index.d.ts +5 -0
- package/dist/types/components/ChaynsProvider.d.ts +21 -0
- package/dist/types/constants/index.d.ts +0 -2
- package/dist/types/contexts/HistoryLayerContext.d.ts +33 -0
- package/dist/types/contexts/index.d.ts +3 -0
- package/dist/types/handler/history/FrameHistoryLayer.d.ts +99 -0
- package/dist/types/handler/history/HistoryLayer.d.ts +117 -0
- package/dist/types/handler/history/index.d.ts +2 -0
- package/dist/types/hooks/history.d.ts +89 -0
- package/dist/types/hooks/index.d.ts +1 -0
- package/dist/types/host/ChaynsHost.d.ts +12 -0
- package/dist/types/host/iframe/HostIframe.d.ts +4 -0
- package/dist/types/host/module/ModuleHost.d.ts +4 -0
- package/dist/types/index.d.ts +15 -6
- package/dist/types/types/IChaynsReact.d.ts +3 -0
- package/dist/types/types/history.d.ts +74 -0
- package/dist/types/umd.index.d.ts +2 -2
- package/dist/types/utils/EventBus.d.ts +10 -0
- package/dist/types/{util → utils}/collectCssChunks.d.ts +1 -1
- package/dist/types/utils/equality.d.ts +2 -0
- package/dist/types/utils/history/BlockRegistry.d.ts +38 -0
- package/dist/types/utils/history/NavigationQueue.d.ts +109 -0
- package/dist/types/utils/history/layerTree.d.ts +10 -0
- package/dist/types/utils/history/navigationIndex.d.ts +14 -0
- package/dist/types/utils/history/rootLayer.d.ts +42 -0
- package/dist/types/utils/history/segments.d.ts +2 -0
- package/dist/types/utils/history/stateProjector.d.ts +24 -0
- package/dist/types/utils/history/url.d.ts +17 -0
- package/dist/types/utils/history/window.d.ts +1 -0
- package/dist/types/wrapper/FrameWrapper.d.ts +1 -0
- package/dist/types/wrapper/StaticChaynsApi.d.ts +1 -0
- package/package.json +2 -1
- /package/dist/cjs/{constants → contexts}/hydrationContext.js +0 -0
- /package/dist/cjs/{constants → contexts}/moduleContext.js +0 -0
- /package/dist/cjs/{helper/apiListenerHelper.js → utils/apiListener.js} +0 -0
- /package/dist/cjs/{util → utils}/appCall.js +0 -0
- /package/dist/cjs/{util → utils}/bindChaynsApi.js +0 -0
- /package/dist/cjs/{util → utils}/collectCssChunks.js +0 -0
- /package/dist/cjs/{util → utils}/deviceHelper.js +0 -0
- /package/dist/cjs/{util → utils}/heightHelper.js +0 -0
- /package/dist/cjs/{util → utils}/initModuleFederationSharing.js +0 -0
- /package/dist/cjs/{util → utils}/is.js +0 -0
- /package/dist/cjs/{util → utils}/postIframeForm.js +0 -0
- /package/dist/cjs/{util → utils}/transferNestedFunctions.js +0 -0
- /package/dist/cjs/{util → utils}/url.js +0 -0
- /package/dist/esm/{constants → contexts}/hydrationContext.js +0 -0
- /package/dist/esm/{constants → contexts}/moduleContext.js +0 -0
- /package/dist/esm/{helper/apiListenerHelper.js → utils/apiListener.js} +0 -0
- /package/dist/esm/{util → utils}/appCall.js +0 -0
- /package/dist/esm/{util → utils}/bindChaynsApi.js +0 -0
- /package/dist/esm/{util → utils}/collectCssChunks.js +0 -0
- /package/dist/esm/{util → utils}/deviceHelper.js +0 -0
- /package/dist/esm/{util → utils}/heightHelper.js +0 -0
- /package/dist/esm/{util → utils}/initModuleFederationSharing.js +0 -0
- /package/dist/esm/{util → utils}/is.js +0 -0
- /package/dist/esm/{util → utils}/postIframeForm.js +0 -0
- /package/dist/esm/{util → utils}/transferNestedFunctions.js +0 -0
- /package/dist/esm/{util → utils}/url.js +0 -0
- /package/dist/types/{constants → contexts}/hydrationContext.d.ts +0 -0
- /package/dist/types/{constants → contexts}/moduleContext.d.ts +0 -0
- /package/dist/types/{helper/apiListenerHelper.d.ts → utils/apiListener.d.ts} +0 -0
- /package/dist/types/{util → utils}/appCall.d.ts +0 -0
- /package/dist/types/{util → utils}/appStorage.d.ts +0 -0
- /package/dist/types/{util → utils}/bindChaynsApi.d.ts +0 -0
- /package/dist/types/{util → utils}/deviceHelper.d.ts +0 -0
- /package/dist/types/{util → utils}/heightHelper.d.ts +0 -0
- /package/dist/types/{util → utils}/initModuleFederationSharing.d.ts +0 -0
- /package/dist/types/{util → utils}/is.d.ts +0 -0
- /package/dist/types/{util → utils}/postIframeForm.d.ts +0 -0
- /package/dist/types/{util → utils}/transferNestedFunctions.d.ts +0 -0
- /package/dist/types/{util → utils}/url.d.ts +0 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.NavigationQueue = void 0;
|
|
7
|
+
var _window = require("./window");
|
|
8
|
+
var _equality = require("../equality");
|
|
9
|
+
class NavigationQueue {
|
|
10
|
+
queue = [];
|
|
11
|
+
isRunning = false;
|
|
12
|
+
constructor(deps) {
|
|
13
|
+
this.deps = deps;
|
|
14
|
+
}
|
|
15
|
+
enqueue(op) {
|
|
16
|
+
return new Promise(resolve => {
|
|
17
|
+
this.queue.push({
|
|
18
|
+
op,
|
|
19
|
+
resolve
|
|
20
|
+
});
|
|
21
|
+
void this.tick();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async tick() {
|
|
25
|
+
if (this.isRunning) return;
|
|
26
|
+
this.isRunning = true;
|
|
27
|
+
try {
|
|
28
|
+
while (this.queue.length > 0) {
|
|
29
|
+
const entry = this.queue.shift();
|
|
30
|
+
try {
|
|
31
|
+
const result = await this.process(entry.op);
|
|
32
|
+
entry.resolve(result);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
entry.resolve({
|
|
35
|
+
isOk: false,
|
|
36
|
+
reason: 'error',
|
|
37
|
+
error
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} finally {
|
|
42
|
+
this.isRunning = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async process(op) {
|
|
46
|
+
switch (op.kind) {
|
|
47
|
+
case 'setRoute':
|
|
48
|
+
return this.processSetRoute(op);
|
|
49
|
+
case 'setState':
|
|
50
|
+
return this.processSetState(op);
|
|
51
|
+
case 'setParams':
|
|
52
|
+
return this.processSetParams(op);
|
|
53
|
+
case 'setHash':
|
|
54
|
+
return this.processSetHash(op);
|
|
55
|
+
case 'setActiveChild':
|
|
56
|
+
return this.processSetActiveChild(op);
|
|
57
|
+
case 'navigate':
|
|
58
|
+
return this.processNavigate(op);
|
|
59
|
+
case 'popstate':
|
|
60
|
+
return this.processPopstate(op);
|
|
61
|
+
default:
|
|
62
|
+
{
|
|
63
|
+
const _exhaustive = op;
|
|
64
|
+
return {
|
|
65
|
+
isOk: false,
|
|
66
|
+
reason: 'error',
|
|
67
|
+
error: new Error('Unknown op')
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async processSetRoute(op) {
|
|
73
|
+
const layer = this.resolveActiveLayer(op.layerId);
|
|
74
|
+
if (!layer) return {
|
|
75
|
+
isOk: false,
|
|
76
|
+
reason: 'stale'
|
|
77
|
+
};
|
|
78
|
+
const allowed = await this.deps.checkBlocks(layer);
|
|
79
|
+
if (!allowed) return {
|
|
80
|
+
isOk: false,
|
|
81
|
+
reason: 'blocked'
|
|
82
|
+
};
|
|
83
|
+
const prevSegments = layer._getOwnSegments();
|
|
84
|
+
const prevParams = layer._getOwnParams();
|
|
85
|
+
const prevHash = layer._getOwnHash();
|
|
86
|
+
layer._setOwnSegmentsSilent(op.segments);
|
|
87
|
+
if (op.opts.params !== undefined) layer._setOwnParamsSilent(op.opts.params);
|
|
88
|
+
if (op.opts.hash !== undefined) layer._setOwnHashSilent(op.opts.hash);
|
|
89
|
+
const changed = op._notifyEvenIfUnchanged === true || !(0, _equality.shallowEqualArr)(prevSegments, op.segments) || op.opts.params !== undefined && !(0, _equality.shallowEqualObj)(prevParams, op.opts.params) || op.opts.hash !== undefined && prevHash !== op.opts.hash;
|
|
90
|
+
if (changed) {
|
|
91
|
+
if (op._skipCommit !== true) {
|
|
92
|
+
this.commit(op.opts.isReplace === true);
|
|
93
|
+
}
|
|
94
|
+
layer._emit('change');
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
isOk: true
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async processSetParams(op) {
|
|
101
|
+
const layer = this.resolveActiveLayer(op.layerId);
|
|
102
|
+
if (!layer) return {
|
|
103
|
+
isOk: false,
|
|
104
|
+
reason: 'stale'
|
|
105
|
+
};
|
|
106
|
+
const allowed = await this.deps.checkBlocks(layer);
|
|
107
|
+
if (!allowed) return {
|
|
108
|
+
isOk: false,
|
|
109
|
+
reason: 'blocked'
|
|
110
|
+
};
|
|
111
|
+
const prev = layer._getOwnParams();
|
|
112
|
+
layer._setOwnParamsSilent(op.params);
|
|
113
|
+
if (!(0, _equality.shallowEqualObj)(prev, op.params)) {
|
|
114
|
+
this.commit(op.opts.isReplace === true);
|
|
115
|
+
layer._emit('change');
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
isOk: true
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async processSetHash(op) {
|
|
122
|
+
const layer = this.resolveActiveLayer(op.layerId);
|
|
123
|
+
if (!layer) return {
|
|
124
|
+
isOk: false,
|
|
125
|
+
reason: 'stale'
|
|
126
|
+
};
|
|
127
|
+
const allowed = await this.deps.checkBlocks(layer);
|
|
128
|
+
if (!allowed) return {
|
|
129
|
+
isOk: false,
|
|
130
|
+
reason: 'blocked'
|
|
131
|
+
};
|
|
132
|
+
const prev = layer._getOwnHash();
|
|
133
|
+
layer._setOwnHashSilent(op.hash);
|
|
134
|
+
if (prev !== op.hash) {
|
|
135
|
+
this.commit(op.opts.isReplace === true);
|
|
136
|
+
layer._emit('change');
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
isOk: true
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
async processSetState(op) {
|
|
143
|
+
const layer = this.resolveActiveLayer(op.layerId);
|
|
144
|
+
if (!layer) return {
|
|
145
|
+
isOk: false,
|
|
146
|
+
reason: 'stale'
|
|
147
|
+
};
|
|
148
|
+
const allowed = await this.deps.checkBlocks(layer);
|
|
149
|
+
if (!allowed) return {
|
|
150
|
+
isOk: false,
|
|
151
|
+
reason: 'blocked'
|
|
152
|
+
};
|
|
153
|
+
const previous = layer._getOwnState();
|
|
154
|
+
layer._setOwnStateSilent(op.state);
|
|
155
|
+
const changed = !(0, _equality.shallowEqualObj)(previous, op.state);
|
|
156
|
+
if (changed) {
|
|
157
|
+
this.commit(op.opts.isReplace === true);
|
|
158
|
+
layer._emit('change');
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
isOk: true
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
async processSetActiveChild(op) {
|
|
165
|
+
const layer = this.resolveActiveLayer(op.layerId);
|
|
166
|
+
if (!layer) return {
|
|
167
|
+
isOk: false,
|
|
168
|
+
reason: 'stale'
|
|
169
|
+
};
|
|
170
|
+
const allowed = await this.deps.checkBlocks(layer);
|
|
171
|
+
if (!allowed) return {
|
|
172
|
+
isOk: false,
|
|
173
|
+
reason: 'blocked'
|
|
174
|
+
};
|
|
175
|
+
const previousUrl = this.deps.projectUrl();
|
|
176
|
+
const previousId = layer.getActiveChildId();
|
|
177
|
+
if (op.childId !== null && !layer.getChildLayer(op.childId)) {
|
|
178
|
+
layer.createChildLayer(op.childId);
|
|
179
|
+
}
|
|
180
|
+
layer._setActiveChildSilent(op.childId);
|
|
181
|
+
let childDataChanged = false;
|
|
182
|
+
if (op.childId && op.init) {
|
|
183
|
+
const child = layer.getChildLayer(op.childId);
|
|
184
|
+
if (child) {
|
|
185
|
+
if (op.init.route) {
|
|
186
|
+
child._setOwnSegmentsSilent(op.init.route);
|
|
187
|
+
childDataChanged = true;
|
|
188
|
+
}
|
|
189
|
+
if (op.init.state) {
|
|
190
|
+
child._setOwnStateSilent(op.init.state);
|
|
191
|
+
childDataChanged = true;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (op.childId) {
|
|
196
|
+
const child = layer.getChildLayer(op.childId);
|
|
197
|
+
if (child && child._getOwnSegments().length === 0 && child.getSegmentCount() > 0) {
|
|
198
|
+
const root = this.deps.getRoot();
|
|
199
|
+
const bootstrapSegs = root._consumeBootstrapSegments(child.getSegmentCount());
|
|
200
|
+
if (bootstrapSegs) {
|
|
201
|
+
child._setOwnSegmentsSilent(bootstrapSegs);
|
|
202
|
+
childDataChanged = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (previousId !== op.childId) {
|
|
207
|
+
const nextUrl = this.deps.projectUrl();
|
|
208
|
+
const shouldReplace = previousUrl === nextUrl;
|
|
209
|
+
this.commit(shouldReplace);
|
|
210
|
+
layer._emit('change');
|
|
211
|
+
}
|
|
212
|
+
if (childDataChanged && op.childId) {
|
|
213
|
+
const child = layer.getChildLayer(op.childId);
|
|
214
|
+
if (child) child._emit('change');
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
isOk: true
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
async processNavigate(op) {
|
|
221
|
+
const layer = this.resolveActiveLayer(op.layerId);
|
|
222
|
+
if (!layer) return {
|
|
223
|
+
isOk: false,
|
|
224
|
+
reason: 'stale'
|
|
225
|
+
};
|
|
226
|
+
const allowed = await this.deps.checkBlocks(layer);
|
|
227
|
+
if (!allowed) return {
|
|
228
|
+
isOk: false,
|
|
229
|
+
reason: 'blocked'
|
|
230
|
+
};
|
|
231
|
+
const prevSeg = layer._getOwnSegments();
|
|
232
|
+
const prevState = layer._getOwnState();
|
|
233
|
+
const prevParams = layer._getOwnParams();
|
|
234
|
+
const prevHash = layer._getOwnHash();
|
|
235
|
+
const prevActiveChild = layer.getActiveChildId();
|
|
236
|
+
if (op.route) layer._setOwnSegmentsSilent(op.route);
|
|
237
|
+
if (op.state) layer._setOwnStateSilent(op.state);
|
|
238
|
+
if (op.params !== undefined) layer._setOwnParamsSilent(op.params);
|
|
239
|
+
if (op.hash !== undefined) layer._setOwnHashSilent(op.hash);
|
|
240
|
+
const segChanged = op.route ? !(0, _equality.shallowEqualArr)(prevSeg, op.route) : false;
|
|
241
|
+
const stateChanged = op.state ? !(0, _equality.shallowEqualObj)(prevState, op.state) : false;
|
|
242
|
+
const paramsChanged = op.params !== undefined ? !(0, _equality.shallowEqualObj)(prevParams, op.params) : false;
|
|
243
|
+
const hashChanged = op.hash !== undefined ? prevHash !== op.hash : false;
|
|
244
|
+
let activeChildChanged = false;
|
|
245
|
+
let childDataChanged = false;
|
|
246
|
+
if (op.activeChild !== undefined) {
|
|
247
|
+
if (op.activeChild !== null && !layer.getChildLayer(op.activeChild)) {
|
|
248
|
+
layer.createChildLayer(op.activeChild);
|
|
249
|
+
}
|
|
250
|
+
layer._setActiveChildSilent(op.activeChild);
|
|
251
|
+
activeChildChanged = prevActiveChild !== op.activeChild;
|
|
252
|
+
if (op.activeChild && op.activeChildInit) {
|
|
253
|
+
const child = layer.getChildLayer(op.activeChild);
|
|
254
|
+
if (child) {
|
|
255
|
+
if (op.activeChildInit.route) {
|
|
256
|
+
child._setOwnSegmentsSilent(op.activeChildInit.route);
|
|
257
|
+
childDataChanged = true;
|
|
258
|
+
}
|
|
259
|
+
if (op.activeChildInit.state) {
|
|
260
|
+
child._setOwnStateSilent(op.activeChildInit.state);
|
|
261
|
+
childDataChanged = true;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (op.activeChild) {
|
|
266
|
+
const child = layer.getChildLayer(op.activeChild);
|
|
267
|
+
if (child && child._getOwnSegments().length === 0 && child.getSegmentCount() > 0) {
|
|
268
|
+
const root = this.deps.getRoot();
|
|
269
|
+
const bootstrapSegs = root._consumeBootstrapSegments(child.getSegmentCount());
|
|
270
|
+
if (bootstrapSegs) {
|
|
271
|
+
child._setOwnSegmentsSilent(bootstrapSegs);
|
|
272
|
+
childDataChanged = true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (segChanged || stateChanged || paramsChanged || hashChanged || activeChildChanged) {
|
|
278
|
+
this.commit(op.opts.isReplace === true);
|
|
279
|
+
layer._emit('change');
|
|
280
|
+
}
|
|
281
|
+
if (childDataChanged && op.activeChild) {
|
|
282
|
+
const child = layer.getChildLayer(op.activeChild);
|
|
283
|
+
if (child) child._emit('change');
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
isOk: true
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
async processPopstate(op) {
|
|
290
|
+
const {
|
|
291
|
+
changedLayerIds
|
|
292
|
+
} = this.deps.diffIncomingState(op.rawState);
|
|
293
|
+
const currentProjectedUrl = this.deps.projectUrl();
|
|
294
|
+
const browserPathname = (0, _window.hasWindowHistory)() ? window.location.pathname : '';
|
|
295
|
+
if (browserPathname && browserPathname !== new URL(currentProjectedUrl, 'http://x').pathname) {
|
|
296
|
+
changedLayerIds.add(this.deps.getRoot().id);
|
|
297
|
+
}
|
|
298
|
+
const target = this.resolveLowestCommonLayer(changedLayerIds);
|
|
299
|
+
if (target) {
|
|
300
|
+
const allowed = await this.deps.checkBlocks(target);
|
|
301
|
+
if (!allowed) {
|
|
302
|
+
await this.deps.silentGo(+1);
|
|
303
|
+
return {
|
|
304
|
+
isOk: false,
|
|
305
|
+
reason: 'blocked'
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const {
|
|
310
|
+
changedLayerIds: applied
|
|
311
|
+
} = this.deps.applyIncomingState(op.rawState);
|
|
312
|
+
const {
|
|
313
|
+
changedLayerIds: urlChanged
|
|
314
|
+
} = this.deps.applyUrlSegments();
|
|
315
|
+
const allChanged = new Set([...applied, ...urlChanged]);
|
|
316
|
+
for (const id of allChanged) {
|
|
317
|
+
const layer = this.deps.findLayer(id);
|
|
318
|
+
if (layer) layer._emit('popstate');
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
isOk: true
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
resolveActiveLayer(id) {
|
|
325
|
+
const layer = this.deps.findLayer(id);
|
|
326
|
+
if (!layer) {
|
|
327
|
+
return undefined;
|
|
328
|
+
}
|
|
329
|
+
if (layer._isDestroyed()) {
|
|
330
|
+
return undefined;
|
|
331
|
+
}
|
|
332
|
+
if (!layer._isInActiveChain()) {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
return layer;
|
|
336
|
+
}
|
|
337
|
+
resolveLowestCommonLayer(ids) {
|
|
338
|
+
if (ids.size === 0) return undefined;
|
|
339
|
+
const ancestorLists = [];
|
|
340
|
+
for (const id of ids) {
|
|
341
|
+
const layer = this.deps.findLayer(id);
|
|
342
|
+
if (!layer) continue;
|
|
343
|
+
const ancestors = [];
|
|
344
|
+
let node = layer;
|
|
345
|
+
while (node) {
|
|
346
|
+
var _node$parent;
|
|
347
|
+
ancestors.unshift(node);
|
|
348
|
+
node = (_node$parent = node.parent) !== null && _node$parent !== void 0 ? _node$parent : null;
|
|
349
|
+
}
|
|
350
|
+
ancestorLists.push(ancestors);
|
|
351
|
+
}
|
|
352
|
+
if (ancestorLists.length === 0) return undefined;
|
|
353
|
+
if (ancestorLists.length === 1) return ancestorLists[0][ancestorLists[0].length - 1];
|
|
354
|
+
let lca;
|
|
355
|
+
const minLen = Math.min(...ancestorLists.map(a => a.length));
|
|
356
|
+
for (let d = 0; d < minLen; d++) {
|
|
357
|
+
const candidate = ancestorLists[0][d];
|
|
358
|
+
if (ancestorLists.every(a => {
|
|
359
|
+
var _a$d;
|
|
360
|
+
return ((_a$d = a[d]) === null || _a$d === void 0 ? void 0 : _a$d.id) === candidate.id;
|
|
361
|
+
})) {
|
|
362
|
+
lca = candidate;
|
|
363
|
+
} else {
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return lca;
|
|
368
|
+
}
|
|
369
|
+
commit(isReplace) {
|
|
370
|
+
if (!(0, _window.hasWindowHistory)()) return;
|
|
371
|
+
const url = this.deps.projectUrl();
|
|
372
|
+
const state = this.deps.projectState();
|
|
373
|
+
const idx = isReplace ? this.deps.getCurrentIdx() : this.deps.incrementIdx();
|
|
374
|
+
const stateWithMeta = {
|
|
375
|
+
...state,
|
|
376
|
+
__chaynsHistory: {
|
|
377
|
+
...state.__chaynsHistory,
|
|
378
|
+
__idx: idx
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
if (isReplace) {
|
|
382
|
+
window.history.replaceState(stateWithMeta, '', url);
|
|
383
|
+
} else {
|
|
384
|
+
window.history.pushState(stateWithMeta, '', url);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
exports.NavigationQueue = NavigationQueue;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.findChaynsHistoryLayerById = findChaynsHistoryLayerById;
|
|
7
|
+
exports.getChaynsHistoryActiveChain = getChaynsHistoryActiveChain;
|
|
8
|
+
exports.isInChaynsHistoryActiveChain = isInChaynsHistoryActiveChain;
|
|
9
|
+
function getChaynsHistoryActiveChain(root) {
|
|
10
|
+
const chain = [root];
|
|
11
|
+
let current = root;
|
|
12
|
+
for (;;) {
|
|
13
|
+
const childId = current.getActiveChildId();
|
|
14
|
+
if (!childId) break;
|
|
15
|
+
const child = current.getChildLayer(childId);
|
|
16
|
+
if (!child) break;
|
|
17
|
+
chain.push(child);
|
|
18
|
+
current = child;
|
|
19
|
+
}
|
|
20
|
+
return chain;
|
|
21
|
+
}
|
|
22
|
+
function findChaynsHistoryLayerById(root, id) {
|
|
23
|
+
if (root.id === id) return root;
|
|
24
|
+
for (const child of root._getChildren().values()) {
|
|
25
|
+
const found = findChaynsHistoryLayerById(child, id);
|
|
26
|
+
if (found) return found;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
function isInChaynsHistoryActiveChain(layer) {
|
|
31
|
+
return layer._isInActiveChain();
|
|
32
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.consumeSilent = consumeSilent;
|
|
7
|
+
exports.getCurrentIdx = getCurrentIdx;
|
|
8
|
+
exports.incrementIdx = incrementIdx;
|
|
9
|
+
exports.silentGo = silentGo;
|
|
10
|
+
var _window = require("./window");
|
|
11
|
+
let currentIdx = 0;
|
|
12
|
+
let pendingSilentCount = 0;
|
|
13
|
+
let silentResolve = null;
|
|
14
|
+
function incrementIdx() {
|
|
15
|
+
return ++currentIdx;
|
|
16
|
+
}
|
|
17
|
+
function getCurrentIdx() {
|
|
18
|
+
return currentIdx;
|
|
19
|
+
}
|
|
20
|
+
function silentGo(delta) {
|
|
21
|
+
if (!(0, _window.hasWindowHistory)()) return Promise.resolve();
|
|
22
|
+
return new Promise(resolve => {
|
|
23
|
+
pendingSilentCount++;
|
|
24
|
+
window.history.go(delta);
|
|
25
|
+
const timeout = setTimeout(() => {
|
|
26
|
+
silentResolve = null;
|
|
27
|
+
resolve();
|
|
28
|
+
}, 2000);
|
|
29
|
+
silentResolve = () => {
|
|
30
|
+
clearTimeout(timeout);
|
|
31
|
+
resolve();
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function consumeSilent() {
|
|
36
|
+
if (pendingSilentCount <= 0) return false;
|
|
37
|
+
pendingSilentCount--;
|
|
38
|
+
const res = silentResolve;
|
|
39
|
+
silentResolve = null;
|
|
40
|
+
res === null || res === void 0 || res();
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getOrInitRootChaynsHistoryLayer = getOrInitRootChaynsHistoryLayer;
|
|
7
|
+
exports.initRootChaynsHistoryLayer = initRootChaynsHistoryLayer;
|
|
8
|
+
exports.resolveSegmentsFrom = resolveSegmentsFrom;
|
|
9
|
+
var _HistoryLayer = require("../../handler/history/HistoryLayer");
|
|
10
|
+
var _NavigationQueue = require("./NavigationQueue");
|
|
11
|
+
var _BlockRegistry = require("./BlockRegistry");
|
|
12
|
+
var _layerTree = require("./layerTree");
|
|
13
|
+
var _url = require("./url");
|
|
14
|
+
var _stateProjector = require("./stateProjector");
|
|
15
|
+
var _navigationIndex = require("./navigationIndex");
|
|
16
|
+
var _window = require("./window");
|
|
17
|
+
var _equality = require("../equality");
|
|
18
|
+
var _calls = require("../../calls");
|
|
19
|
+
var _segments = require("./segments");
|
|
20
|
+
function getInitialPathname(overrideUrl) {
|
|
21
|
+
if (overrideUrl) {
|
|
22
|
+
try {
|
|
23
|
+
return new URL(overrideUrl).pathname;
|
|
24
|
+
} catch {}
|
|
25
|
+
return overrideUrl.startsWith('/') ? overrideUrl : `/${overrideUrl}`;
|
|
26
|
+
}
|
|
27
|
+
if ((0, _window.hasWindowHistory)()) {
|
|
28
|
+
return window.location.pathname;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const siteUrl = (0, _calls.getSite)().url;
|
|
32
|
+
if (siteUrl) return new URL(siteUrl).pathname;
|
|
33
|
+
} catch {}
|
|
34
|
+
return '/';
|
|
35
|
+
}
|
|
36
|
+
function resolveInitialSegments(overrideUrl, n) {
|
|
37
|
+
const pathname = getInitialPathname(overrideUrl);
|
|
38
|
+
const all = pathname.replace(/^\//, '').split('/').filter(Boolean);
|
|
39
|
+
const taken = all.slice(0, n);
|
|
40
|
+
while (taken.length < n) taken.push('');
|
|
41
|
+
return taken;
|
|
42
|
+
}
|
|
43
|
+
function resolveSegmentsFrom(overrideUrl, startIndex) {
|
|
44
|
+
const pathname = getInitialPathname(overrideUrl);
|
|
45
|
+
const all = pathname.replace(/^\//, '').split('/').filter(Boolean);
|
|
46
|
+
return all.slice(startIndex);
|
|
47
|
+
}
|
|
48
|
+
function initRootChaynsHistoryLayer(opts = {}) {
|
|
49
|
+
var _opts$segmentCount;
|
|
50
|
+
const blockRegistry = new _BlockRegistry.BlockRegistry();
|
|
51
|
+
let rootLayer;
|
|
52
|
+
let queue;
|
|
53
|
+
const deps = {
|
|
54
|
+
getRoot: () => rootLayer,
|
|
55
|
+
getQueue: () => queue,
|
|
56
|
+
getBlockRegistry: () => blockRegistry
|
|
57
|
+
};
|
|
58
|
+
rootLayer = new _HistoryLayer.ChaynsHistoryLayer({
|
|
59
|
+
id: 'root',
|
|
60
|
+
parent: null,
|
|
61
|
+
deps,
|
|
62
|
+
segmentCount: (_opts$segmentCount = opts.segmentCount) !== null && _opts$segmentCount !== void 0 ? _opts$segmentCount : 0,
|
|
63
|
+
segments: opts.segmentCount ? resolveInitialSegments(opts.url, opts.segmentCount) : []
|
|
64
|
+
});
|
|
65
|
+
queue = new _NavigationQueue.NavigationQueue({
|
|
66
|
+
getRoot: () => rootLayer,
|
|
67
|
+
findLayer: id => (0, _layerTree.findChaynsHistoryLayerById)(rootLayer, id),
|
|
68
|
+
checkBlocks: target => blockRegistry.checkBlocks(target),
|
|
69
|
+
projectUrl: () => (0, _url.projectToUrl)(rootLayer),
|
|
70
|
+
projectState: () => {
|
|
71
|
+
var _ref;
|
|
72
|
+
const existing = (0, _window.hasWindowHistory)() ? {
|
|
73
|
+
...((_ref = window.history.state) !== null && _ref !== void 0 ? _ref : {})
|
|
74
|
+
} : {};
|
|
75
|
+
delete existing.__chaynsHistory;
|
|
76
|
+
return (0, _stateProjector.projectToState)(rootLayer, existing);
|
|
77
|
+
},
|
|
78
|
+
diffIncomingState: raw => (0, _stateProjector.diffIncomingState)(rootLayer, raw),
|
|
79
|
+
applyIncomingState: raw => (0, _stateProjector.applyStateToTree)(rootLayer, raw),
|
|
80
|
+
silentGo: delta => (0, _navigationIndex.silentGo)(delta),
|
|
81
|
+
getCurrentIdx: () => (0, _navigationIndex.getCurrentIdx)(),
|
|
82
|
+
incrementIdx: () => (0, _navigationIndex.incrementIdx)(),
|
|
83
|
+
applyUrlSegments: () => {
|
|
84
|
+
if (!(0, _window.hasWindowHistory)()) return {
|
|
85
|
+
changedLayerIds: new Set()
|
|
86
|
+
};
|
|
87
|
+
const {
|
|
88
|
+
perLayerSegments
|
|
89
|
+
} = (0, _url.parseFromUrl)(window.location.pathname, rootLayer);
|
|
90
|
+
const changed = new Set();
|
|
91
|
+
for (const [id, segs] of perLayerSegments) {
|
|
92
|
+
const layer = (0, _layerTree.findChaynsHistoryLayerById)(rootLayer, id);
|
|
93
|
+
if (!layer) continue;
|
|
94
|
+
const normalizedSegs = (0, _segments.normalizeHistorySegments)(segs);
|
|
95
|
+
const prev = layer._getOwnSegments();
|
|
96
|
+
if (!(0, _equality.shallowEqualArr)(prev, normalizedSegs)) {
|
|
97
|
+
layer._setOwnSegmentsSilent(normalizedSegs);
|
|
98
|
+
changed.add(id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
changedLayerIds: changed
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
const existingState = (0, _window.hasWindowHistory)() ? window.history.state : null;
|
|
107
|
+
if (!(0, _stateProjector.hasChaynsHistoryState)(existingState)) {
|
|
108
|
+
var _opts$segmentCount2, _opts$url;
|
|
109
|
+
const segmentCount = (_opts$segmentCount2 = opts.segmentCount) !== null && _opts$segmentCount2 !== void 0 ? _opts$segmentCount2 : 0;
|
|
110
|
+
if (segmentCount > 0) {
|
|
111
|
+
const pathname = getInitialPathname(opts.url);
|
|
112
|
+
const all = pathname.replace(/^\//, '').split('/').filter(Boolean);
|
|
113
|
+
rootLayer._setBootstrapPool(all.slice(segmentCount));
|
|
114
|
+
} else {
|
|
115
|
+
rootLayer._setBootstrapUrlResolver(() => getInitialPathname(opts.url));
|
|
116
|
+
}
|
|
117
|
+
const rawUrl = (_opts$url = opts.url) !== null && _opts$url !== void 0 ? _opts$url : (0, _window.hasWindowHistory)() ? window.location.href : null;
|
|
118
|
+
if (rawUrl) {
|
|
119
|
+
try {
|
|
120
|
+
const base = rawUrl.startsWith('http') ? rawUrl : `http://x${rawUrl.startsWith('/') ? rawUrl : '/' + rawUrl}`;
|
|
121
|
+
const parsed = new URL(base);
|
|
122
|
+
const params = {};
|
|
123
|
+
parsed.searchParams.forEach((v, k) => {
|
|
124
|
+
params[k] = v;
|
|
125
|
+
});
|
|
126
|
+
if (Object.keys(params).length > 0) rootLayer._setOwnParamsSilent(params);
|
|
127
|
+
const hash = parsed.hash.replace(/^#/, '');
|
|
128
|
+
if (hash) rootLayer._setOwnHashSilent(hash);
|
|
129
|
+
} catch {}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if ((0, _window.hasWindowHistory)()) {
|
|
133
|
+
const existing = existingState;
|
|
134
|
+
if (!(0, _stateProjector.hasChaynsHistoryState)(existing)) {
|
|
135
|
+
const foreign = {
|
|
136
|
+
...(existing !== null && existing !== void 0 ? existing : {})
|
|
137
|
+
};
|
|
138
|
+
delete foreign.__chaynsHistory;
|
|
139
|
+
const initialState = (0, _stateProjector.projectToState)(rootLayer, foreign);
|
|
140
|
+
const idx = (0, _navigationIndex.incrementIdx)();
|
|
141
|
+
window.history.replaceState({
|
|
142
|
+
...initialState,
|
|
143
|
+
__chaynsHistory: {
|
|
144
|
+
...initialState.__chaynsHistory,
|
|
145
|
+
__idx: idx
|
|
146
|
+
}
|
|
147
|
+
}, '', window.location.href);
|
|
148
|
+
} else {
|
|
149
|
+
(0, _stateProjector.applyStateToTree)(rootLayer, existing);
|
|
150
|
+
}
|
|
151
|
+
window.addEventListener('popstate', event => {
|
|
152
|
+
if ((0, _navigationIndex.consumeSilent)()) return;
|
|
153
|
+
const raw = event.state;
|
|
154
|
+
if (!(0, _stateProjector.hasChaynsHistoryState)(raw)) {} else {
|
|
155
|
+
void queue.enqueue({
|
|
156
|
+
kind: 'popstate',
|
|
157
|
+
rawState: raw
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
rootLayer
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
let _rootLayerResult = null;
|
|
167
|
+
function getOrInitRootChaynsHistoryLayer(url, segmentCount) {
|
|
168
|
+
if (!_rootLayerResult) {
|
|
169
|
+
_rootLayerResult = initRootChaynsHistoryLayer({
|
|
170
|
+
url,
|
|
171
|
+
segmentCount
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return _rootLayerResult;
|
|
175
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.normalizeHistorySegments = exports.normalizeHistoryRouteInput = void 0;
|
|
7
|
+
const normalizeHistorySegments = segments => segments.filter(segment => segment.length > 0);
|
|
8
|
+
exports.normalizeHistorySegments = normalizeHistorySegments;
|
|
9
|
+
const normalizeHistoryRouteInput = route => {
|
|
10
|
+
if (Array.isArray(route)) {
|
|
11
|
+
return normalizeHistorySegments([...route]);
|
|
12
|
+
}
|
|
13
|
+
return route.split('/').filter(Boolean);
|
|
14
|
+
};
|
|
15
|
+
exports.normalizeHistoryRouteInput = normalizeHistoryRouteInput;
|