foldkit 0.82.4 → 0.82.6
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/runtime/browserListeners.d.ts +1 -2
- package/dist/runtime/browserListeners.d.ts.map +1 -1
- package/dist/runtime/browserListeners.js +12 -12
- package/dist/runtime/messagePriority.d.ts +13 -0
- package/dist/runtime/messagePriority.d.ts.map +1 -0
- package/dist/runtime/messagePriority.js +12 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +51 -24
- package/package.json +1 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Queue } from 'effect';
|
|
2
1
|
import { RoutingConfig } from './runtime.js';
|
|
3
|
-
export declare const addNavigationEventListeners: <Message>(
|
|
2
|
+
export declare const addNavigationEventListeners: <Message>(dispatch: (message: Message) => void, routingConfig: RoutingConfig<Message>) => void;
|
|
4
3
|
export declare const addBfcacheRestoreListener: () => void;
|
|
5
4
|
//# sourceMappingURL=browserListeners.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserListeners.d.ts","sourceRoot":"","sources":["../../src/runtime/browserListeners.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browserListeners.d.ts","sourceRoot":"","sources":["../../src/runtime/browserListeners.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAG5C,eAAO,MAAM,2BAA2B,GAAI,OAAO,EACjD,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,EACpC,eAAe,aAAa,CAAC,OAAO,CAAC,SAKtC,CAAA;AA6ED,eAAO,MAAM,yBAAyB,YASrC,CAAA"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { Option,
|
|
1
|
+
import { Option, String } from 'effect';
|
|
2
2
|
import { OptionExt, StringExt } from '../effectExtensions/index.js';
|
|
3
3
|
import { External, Internal } from './urlRequest.js';
|
|
4
|
-
export const addNavigationEventListeners = (
|
|
5
|
-
addPopStateListener(
|
|
6
|
-
addLinkClickListener(
|
|
7
|
-
addProgrammaticNavigationListener(
|
|
4
|
+
export const addNavigationEventListeners = (dispatch, routingConfig) => {
|
|
5
|
+
addPopStateListener(dispatch, routingConfig);
|
|
6
|
+
addLinkClickListener(dispatch, routingConfig);
|
|
7
|
+
addProgrammaticNavigationListener(dispatch, routingConfig);
|
|
8
8
|
};
|
|
9
|
-
const addPopStateListener = (
|
|
9
|
+
const addPopStateListener = (dispatch, routingConfig) => {
|
|
10
10
|
const onPopState = () => {
|
|
11
|
-
|
|
11
|
+
dispatch(routingConfig.onUrlChange(locationToUrl()));
|
|
12
12
|
};
|
|
13
13
|
window.addEventListener('popstate', onPopState);
|
|
14
14
|
};
|
|
15
|
-
const addLinkClickListener = (
|
|
15
|
+
const addLinkClickListener = (dispatch, routingConfig) => {
|
|
16
16
|
const onLinkClick = (event) => {
|
|
17
17
|
const target = event.target;
|
|
18
18
|
if (!(target instanceof Element)) {
|
|
@@ -30,16 +30,16 @@ const addLinkClickListener = (messageQueue, routingConfig) => {
|
|
|
30
30
|
const linkUrl = new URL(href);
|
|
31
31
|
const currentUrl = new URL(window.location.href);
|
|
32
32
|
if (linkUrl.origin !== currentUrl.origin) {
|
|
33
|
-
|
|
33
|
+
dispatch(routingConfig.onUrlRequest(External({ href })));
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
dispatch(routingConfig.onUrlRequest(Internal({ url: urlToFoldkitUrl(linkUrl) })));
|
|
37
37
|
};
|
|
38
38
|
document.addEventListener('click', onLinkClick);
|
|
39
39
|
};
|
|
40
|
-
const addProgrammaticNavigationListener = (
|
|
40
|
+
const addProgrammaticNavigationListener = (dispatch, routingConfig) => {
|
|
41
41
|
const onProgrammaticNavigation = () => {
|
|
42
|
-
|
|
42
|
+
dispatch(routingConfig.onUrlChange(locationToUrl()));
|
|
43
43
|
};
|
|
44
44
|
window.addEventListener('foldkit:urlchange', onProgrammaticNavigation);
|
|
45
45
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type Priority = 'High' | 'Normal';
|
|
2
|
+
export type EnvelopedMessage<Message> = Readonly<{
|
|
3
|
+
priority: Priority;
|
|
4
|
+
message: Message;
|
|
5
|
+
}>;
|
|
6
|
+
/** Reorders a batch of EnvelopedMessages so all `High` envelopes appear
|
|
7
|
+
* before any `Normal` envelope, preserving FIFO order within each priority
|
|
8
|
+
* class. The runtime calls this on each `Queue.takeAll` batch so user input
|
|
9
|
+
* (view dispatch, navigation, subscription events, managed-resource events,
|
|
10
|
+
* external dispatchers) lands ahead of chain-derived work (Command results)
|
|
11
|
+
* whenever both share a frame. */
|
|
12
|
+
export declare const orderByPriority: <Message>(batch: ReadonlyArray<EnvelopedMessage<Message>>) => ReadonlyArray<Message>;
|
|
13
|
+
//# sourceMappingURL=messagePriority.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messagePriority.d.ts","sourceRoot":"","sources":["../../src/runtime/messagePriority.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC/C,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF;;;;;mCAKmC;AACnC,eAAO,MAAM,eAAe,GAAI,OAAO,EACrC,OAAO,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAC9C,aAAa,CAAC,OAAO,CAUvB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Array } from 'effect';
|
|
2
|
+
/** Reorders a batch of EnvelopedMessages so all `High` envelopes appear
|
|
3
|
+
* before any `Normal` envelope, preserving FIFO order within each priority
|
|
4
|
+
* class. The runtime calls this on each `Queue.takeAll` batch so user input
|
|
5
|
+
* (view dispatch, navigation, subscription events, managed-resource events,
|
|
6
|
+
* external dispatchers) lands ahead of chain-derived work (Command results)
|
|
7
|
+
* whenever both share a frame. */
|
|
8
|
+
export const orderByPriority = (batch) => {
|
|
9
|
+
const highs = Array.filter(batch, envelope => envelope.priority === 'High');
|
|
10
|
+
const normals = Array.filter(batch, envelope => envelope.priority === 'Normal');
|
|
11
|
+
return Array.map(Array.appendAll(highs, normals), envelope => envelope.message);
|
|
12
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,OAAO,EACP,MAAM,EAGN,KAAK,EAEL,MAAM,EAON,MAAM,EAIP,MAAM,QAAQ,CAAA;AAGf,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,GAAG,EAA+B,MAAM,iBAAiB,CAAA;AAalE,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/runtime.js
CHANGED
|
@@ -10,6 +10,7 @@ import { addBfcacheRestoreListener, addNavigationEventListeners, } from './brows
|
|
|
10
10
|
import { defaultCrashView, noOpDispatch } from './crashUI.js';
|
|
11
11
|
import { deepFreeze } from './deepFreeze.js';
|
|
12
12
|
import { PreserveModelMessage, RequestModelMessage, RestoreModelMessage, } from './hmrProtocol.js';
|
|
13
|
+
import { orderByPriority } from './messagePriority.js';
|
|
13
14
|
const DEFAULT_DEV_TOOLS_SHOW = 'Development';
|
|
14
15
|
const DEFAULT_DEV_TOOLS_POSITION = 'BottomRight';
|
|
15
16
|
const DEFAULT_DEV_TOOLS_MODE = 'TimeTravel';
|
|
@@ -102,8 +103,18 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
102
103
|
Model);
|
|
103
104
|
const decodeHmrModel = Schema.decodeUnknownExit(ModelJsonCodec);
|
|
104
105
|
const encodeHmrModel = Schema.encodeUnknownSync(ModelJsonCodec);
|
|
106
|
+
// NOTE: Each enqueued Message carries a priority. Within a single
|
|
107
|
+
// takeAll batch the drain loop processes all High before any Normal,
|
|
108
|
+
// so user input (view dispatch, navigation, subscription events,
|
|
109
|
+
// managed-resource events, external dispatchers) lands ahead of
|
|
110
|
+
// chain-derived work (Command results) when they share a frame.
|
|
111
|
+
// FIFO order is preserved within a priority class.
|
|
105
112
|
const messageQueue = yield* Queue.unbounded();
|
|
106
|
-
const
|
|
113
|
+
const enqueueHigh = (message) => Queue.offer(messageQueue, { priority: 'High', message });
|
|
114
|
+
const enqueueNormal = (message) => Queue.offer(messageQueue, { priority: 'Normal', message });
|
|
115
|
+
const enqueueHighUnsafe = (message) => {
|
|
116
|
+
Queue.offerUnsafe(messageQueue, { priority: 'High', message });
|
|
117
|
+
};
|
|
107
118
|
const currentUrl = Option.fromNullishOr(routingConfig).pipe(Option.flatMap(() => urlFromString(window.location.href)));
|
|
108
119
|
const [initModelRaw, initCommands] = Predicate.isNotUndefined(hmrModel)
|
|
109
120
|
? Exit.match(decodeHmrModel(hmrModel), {
|
|
@@ -115,9 +126,9 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
115
126
|
const modelPubSub = yield* PubSub.unbounded();
|
|
116
127
|
yield* Effect.forEach(
|
|
117
128
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
118
|
-
initCommands, command => Effect.forkDetach(command.effect.pipe(Effect.withSpan(command.name), provideAllResources, Effect.flatMap(
|
|
129
|
+
initCommands, command => Effect.forkDetach(command.effect.pipe(Effect.withSpan(command.name), provideAllResources, Effect.flatMap(enqueueNormal))));
|
|
119
130
|
if (routingConfig) {
|
|
120
|
-
addNavigationEventListeners(
|
|
131
|
+
addNavigationEventListeners(enqueueHighUnsafe, routingConfig);
|
|
121
132
|
}
|
|
122
133
|
const modelRef = yield* Ref.make(initModel);
|
|
123
134
|
const maybeCurrentVNodeRef = yield* Ref.make(Option.none());
|
|
@@ -125,13 +136,13 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
125
136
|
const maybeDevToolsStoreRef = yield* Ref.make(Option.none());
|
|
126
137
|
const dispatchSync = (message) => {
|
|
127
138
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
128
|
-
|
|
139
|
+
enqueueHighUnsafe(message);
|
|
129
140
|
};
|
|
130
141
|
const dispatchAsync = (message) =>
|
|
131
142
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
132
|
-
|
|
143
|
+
enqueueHigh(message);
|
|
133
144
|
const dispatch = { dispatchAsync, dispatchSync };
|
|
134
|
-
const isRenderPendingRef = yield*
|
|
145
|
+
const isRenderPendingRef = yield* SubscriptionRef.make(false);
|
|
135
146
|
const lastDirtyMessageRef = yield* Ref.make(Option.none());
|
|
136
147
|
const isPausedEffect = Effect.gen(function* () {
|
|
137
148
|
const maybeStore = yield* Ref.get(maybeDevToolsStoreRef);
|
|
@@ -146,7 +157,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
146
157
|
const nextModel = maybeFreezeModel(nextModelRaw);
|
|
147
158
|
if (currentModel !== nextModel) {
|
|
148
159
|
yield* Ref.set(modelRef, nextModel);
|
|
149
|
-
yield*
|
|
160
|
+
yield* SubscriptionRef.set(isRenderPendingRef, true);
|
|
150
161
|
yield* Ref.set(lastDirtyMessageRef, Option.some(message));
|
|
151
162
|
if (!modelEquivalence(currentModel, nextModel)) {
|
|
152
163
|
PubSub.publishUnsafe(modelPubSub, nextModel);
|
|
@@ -155,7 +166,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
155
166
|
}
|
|
156
167
|
yield* Effect.forEach(
|
|
157
168
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
158
|
-
commands, command => Effect.forkDetach(command.effect.pipe(Effect.withSpan(command.name), provideAllResources, Effect.flatMap(
|
|
169
|
+
commands, command => Effect.forkDetach(command.effect.pipe(Effect.withSpan(command.name), provideAllResources, Effect.flatMap(enqueueNormal))));
|
|
159
170
|
const maybeDevToolsStore = yield* Ref.get(maybeDevToolsStoreRef);
|
|
160
171
|
yield* Option.match(maybeDevToolsStore, {
|
|
161
172
|
onNone: () => Effect.void,
|
|
@@ -203,9 +214,15 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
203
214
|
const [updatedModel] = update(model, message);
|
|
204
215
|
return maybeFreezeModel(updatedModel);
|
|
205
216
|
},
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
217
|
+
// NOTE: clears the dirty bit on direct DevTools renders (jumpTo,
|
|
218
|
+
// resume) so the renderLoop's Stream.changes sees the next
|
|
219
|
+
// dispatch as a real false-to-true transition rather than a
|
|
220
|
+
// deduped no-op.
|
|
221
|
+
render: model => Effect.gen(function* () {
|
|
222
|
+
yield* SubscriptionRef.set(isRenderPendingRef, false);
|
|
223
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
224
|
+
yield* render(model, Option.none());
|
|
225
|
+
}),
|
|
209
226
|
getCurrentModel: Ref.get(modelRef),
|
|
210
227
|
});
|
|
211
228
|
yield* Ref.set(maybeDevToolsStoreRef, Option.some(devToolsStore));
|
|
@@ -217,7 +234,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
217
234
|
: Option.none();
|
|
218
235
|
yield* startWebSocketBridge(devToolsStore, import.meta.hot,
|
|
219
236
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
220
|
-
message =>
|
|
237
|
+
message => enqueueHigh(message),
|
|
221
238
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
222
239
|
maybeMessageSchema);
|
|
223
240
|
}
|
|
@@ -229,21 +246,27 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
229
246
|
// view past threshold. Acceptable for a debug callback; full
|
|
230
247
|
// attribution would require correlating each message with its render
|
|
231
248
|
// contribution, which isn't worth the complexity.
|
|
232
|
-
const
|
|
249
|
+
const renderAtNextFrame = Effect.gen(function* () {
|
|
233
250
|
yield* awaitNextFrame;
|
|
234
|
-
|
|
235
|
-
if (!isPending) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
251
|
+
yield* SubscriptionRef.set(isRenderPendingRef, false);
|
|
238
252
|
const isPaused = yield* isPausedEffect;
|
|
239
253
|
if (isPaused) {
|
|
240
254
|
return;
|
|
241
255
|
}
|
|
242
|
-
yield* Ref.set(isRenderPendingRef, false);
|
|
243
256
|
const model = yield* Ref.get(modelRef);
|
|
244
257
|
const maybeMessage = yield* Ref.get(lastDirtyMessageRef);
|
|
245
258
|
yield* render(model, maybeMessage);
|
|
246
|
-
})
|
|
259
|
+
});
|
|
260
|
+
// NOTE: The loop suspends on the SubscriptionRef's changes Stream when
|
|
261
|
+
// isRenderPending stays false, so an idle app schedules zero rAF
|
|
262
|
+
// callbacks. Stream.changes filters consecutive equals so multiple
|
|
263
|
+
// dispatches inside one frame produce a single render. The bit is
|
|
264
|
+
// cleared on every body run, including the paused early-return, so
|
|
265
|
+
// any future false-to-true transition wakes the loop again. This
|
|
266
|
+
// self-recovery covers indirect unpause paths in the DevTools store
|
|
267
|
+
// (rolling-buffer eviction past pausedAtIndex, and the clear action)
|
|
268
|
+
// that bypass bridge.render.
|
|
269
|
+
const renderLoop = SubscriptionRef.changes(isRenderPendingRef).pipe(Stream.changes, Stream.filter(isPending => isPending), Stream.runForEach(() => renderAtNextFrame));
|
|
247
270
|
yield* Effect.forkDetach(renderLoop);
|
|
248
271
|
addBfcacheRestoreListener();
|
|
249
272
|
if (subscriptions) {
|
|
@@ -261,7 +284,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
261
284
|
return dependencies;
|
|
262
285
|
}), Stream.changesWith(equivalence), Stream.switchMap(dependencies => dependenciesToStream(dependencies, () => latestDependencies)), Stream.runForEach(message =>
|
|
263
286
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
264
|
-
|
|
287
|
+
enqueueHigh(message)), provideAllResources));
|
|
265
288
|
}, {
|
|
266
289
|
concurrency: 'unbounded',
|
|
267
290
|
discard: true,
|
|
@@ -283,14 +306,14 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
283
306
|
const release = (value) => Effect.gen(function* () {
|
|
284
307
|
yield* config.release(value);
|
|
285
308
|
yield* Ref.set(resourceRef, Option.none());
|
|
286
|
-
yield*
|
|
309
|
+
yield* enqueueHigh(config.onReleased());
|
|
287
310
|
}).pipe(Effect.catchCause(() => Effect.void));
|
|
288
311
|
return pipe(Stream.scoped(Stream.fromEffect(Effect.acquireRelease(acquire, release))), Stream.flatMap(value => Stream.concat(Stream.make(config.onAcquired(value)), Stream.never)), Stream.map(Effect.succeed), Stream.catch(error => Stream.make(Effect.succeed(config.onAcquireError(error)))));
|
|
289
312
|
};
|
|
290
313
|
const forkManagedResourceLifecycle = ({ config, ref: resourceRef, }) => Effect.gen(function* () {
|
|
291
314
|
const modelStream = Stream.concat(Stream.make(initModel), Stream.fromPubSub(modelPubSub));
|
|
292
315
|
const equivalence = Schema.toEquivalence(config.schema);
|
|
293
|
-
yield* Effect.forkDetach(modelStream.pipe(Stream.map(config.modelToMaybeRequirements), Stream.changesWith(equivalence), Stream.switchMap(maybeRequirementsToLifecycle(config, resourceRef)), Stream.runForEach(Effect.flatMap(
|
|
316
|
+
yield* Effect.forkDetach(modelStream.pipe(Stream.map(config.modelToMaybeRequirements), Stream.changesWith(equivalence), Stream.switchMap(maybeRequirementsToLifecycle(config, resourceRef)), Stream.runForEach(Effect.flatMap(enqueueHigh))));
|
|
294
317
|
});
|
|
295
318
|
yield* Effect.forEach(managedResourceRefs, forkManagedResourceLifecycle, {
|
|
296
319
|
concurrency: 'unbounded',
|
|
@@ -307,18 +330,22 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
307
330
|
yield* yieldToBrowser;
|
|
308
331
|
yield* Ref.set(burstStartedAtRef, performance.now());
|
|
309
332
|
});
|
|
333
|
+
const processBatch = (batch) => Effect.forEach(orderByPriority(batch), processWithBudget, {
|
|
334
|
+
discard: true,
|
|
335
|
+
});
|
|
310
336
|
const drainQueue = Effect.gen(function* () {
|
|
311
337
|
const batch = yield* Queue.takeAll(messageQueue);
|
|
312
338
|
if (Array.isReadonlyArrayEmpty(batch)) {
|
|
313
339
|
return;
|
|
314
340
|
}
|
|
315
|
-
yield*
|
|
341
|
+
yield* processBatch(batch);
|
|
316
342
|
yield* drainQueue;
|
|
317
343
|
});
|
|
318
344
|
yield* pipe(Effect.forever(Effect.gen(function* () {
|
|
319
345
|
const first = yield* Queue.take(messageQueue);
|
|
346
|
+
const rest = yield* Queue.takeAll(messageQueue);
|
|
320
347
|
yield* Ref.set(burstStartedAtRef, performance.now());
|
|
321
|
-
yield*
|
|
348
|
+
yield* processBatch(Array.prepend(rest, first));
|
|
322
349
|
yield* drainQueue;
|
|
323
350
|
})), Effect.catchCause(cause => Effect.sync(() => {
|
|
324
351
|
const squashed = Cause.squash(cause);
|