@livestore/livestore 0.0.55-dev.0 → 0.0.55-dev.2
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/.tsbuildinfo +1 -1
- package/dist/store-devtools.d.ts +18 -0
- package/dist/store-devtools.d.ts.map +1 -0
- package/dist/store-devtools.js +145 -0
- package/dist/store-devtools.js.map +1 -0
- package/dist/store.d.ts +1 -10
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +48 -189
- package/dist/store.js.map +1 -1
- package/dist/utils/data-structures.d.ts +10 -0
- package/dist/utils/data-structures.d.ts.map +1 -0
- package/dist/utils/data-structures.js +32 -0
- package/dist/utils/data-structures.js.map +1 -0
- package/package.json +5 -5
- package/src/store-devtools.ts +213 -0
- package/src/store.ts +64 -255
- package/src/utils/data-structures.ts +36 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StoreAdapter } from '@livestore/common';
|
|
2
|
+
import { Effect } from '@livestore/utils/effect';
|
|
3
|
+
import type { MainDatabaseWrapper } from './MainDatabaseWrapper.js';
|
|
4
|
+
import type { LiveQuery, ReactivityGraph } from './reactiveQueries/base-class.js';
|
|
5
|
+
import type { ReferenceCountedSet } from './utils/data-structures.js';
|
|
6
|
+
type IStore = {
|
|
7
|
+
adapter: StoreAdapter;
|
|
8
|
+
devtoolsConnectionId: string;
|
|
9
|
+
reactivityGraph: ReactivityGraph;
|
|
10
|
+
mainDbWrapper: MainDatabaseWrapper;
|
|
11
|
+
activeQueries: ReferenceCountedSet<LiveQuery<any>>;
|
|
12
|
+
};
|
|
13
|
+
export declare const connectStoreToDevtools: ({ port, store }: {
|
|
14
|
+
port: MessagePort;
|
|
15
|
+
store: IStore;
|
|
16
|
+
}) => Effect.Effect<void, import("@livestore/common").UnexpectedError | import("@effect/schema/ParseResult").ParseError, import("effect/Scope").Scope>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=store-devtools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-devtools.d.ts","sourceRoot":"","sources":["../src/store-devtools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhE,OAAO,EAAkB,MAAM,EAAU,MAAM,yBAAyB,CAAA;AAExE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAKrE,KAAK,MAAM,GAAG;IACZ,OAAO,EAAE,YAAY,CAAA;IACrB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,eAAe,EAAE,eAAe,CAAA;IAChC,aAAa,EAAE,mBAAmB,CAAA;IAClC,aAAa,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;CACnD,CAAA;AAED,eAAO,MAAM,sBAAsB,oBAAqB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,qJA8LxF,CAAA"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Devtools, liveStoreVersion } from '@livestore/common';
|
|
2
|
+
import { throttle } from '@livestore/utils';
|
|
3
|
+
import { BrowserChannel, Effect, Stream } from '@livestore/utils/effect';
|
|
4
|
+
import { emptyDebugInfo as makeEmptyDebugInfo } from './MainDatabaseWrapper.js';
|
|
5
|
+
import { NOT_REFRESHED_YET } from './reactive.js';
|
|
6
|
+
export const connectStoreToDevtools = ({ port, store }) => Effect.gen(function* () {
|
|
7
|
+
const channelId = store.adapter.coordinator.devtools.channelId;
|
|
8
|
+
const reactivityGraphSubcriptions = new Map();
|
|
9
|
+
const liveQueriesSubscriptions = new Map();
|
|
10
|
+
const debugInfoHistorySubscriptions = new Map();
|
|
11
|
+
const { storeMessagePort } = yield* store.adapter.coordinator.devtools.connect({
|
|
12
|
+
port,
|
|
13
|
+
connectionId: store.devtoolsConnectionId,
|
|
14
|
+
});
|
|
15
|
+
const storePortChannel = yield* BrowserChannel.messagePortChannel({
|
|
16
|
+
port: storeMessagePort,
|
|
17
|
+
listenSchema: Devtools.MessageToAppHostStore,
|
|
18
|
+
sendSchema: Devtools.MessageFromAppHostStore,
|
|
19
|
+
});
|
|
20
|
+
const sendToDevtools = (message) => storePortChannel.send(message).pipe(Effect.tapCauseLogPretty, Effect.runSync);
|
|
21
|
+
const onMessage = (decodedMessage) => {
|
|
22
|
+
// console.log('storeMessagePort message', decodedMessage)
|
|
23
|
+
if (decodedMessage.channelId !== store.adapter.coordinator.devtools.channelId) {
|
|
24
|
+
// console.log(`Unknown message`, event)
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const requestId = decodedMessage.requestId;
|
|
28
|
+
const requestIdleCallback = window.requestIdleCallback ?? ((cb) => cb());
|
|
29
|
+
switch (decodedMessage._tag) {
|
|
30
|
+
case 'LSD.ReactivityGraphSubscribe': {
|
|
31
|
+
const includeResults = decodedMessage.includeResults;
|
|
32
|
+
const send = () =>
|
|
33
|
+
// In order to not add more work to the current tick, we use requestIdleCallback
|
|
34
|
+
// to send the reactivity graph updates to the devtools
|
|
35
|
+
requestIdleCallback(() => sendToDevtools(Devtools.ReactivityGraphRes.make({
|
|
36
|
+
reactivityGraph: store.reactivityGraph.getSnapshot({ includeResults }),
|
|
37
|
+
requestId,
|
|
38
|
+
channelId,
|
|
39
|
+
liveStoreVersion,
|
|
40
|
+
})), { timeout: 500 });
|
|
41
|
+
send();
|
|
42
|
+
// In some cases, there can be A LOT of reactivity graph updates in a short period of time
|
|
43
|
+
// so we throttle the updates to avoid sending too much data
|
|
44
|
+
// This might need to be tweaked further and possibly be exposed to the user in some way.
|
|
45
|
+
const throttledSend = throttle(send, 20);
|
|
46
|
+
reactivityGraphSubcriptions.set(requestId, store.reactivityGraph.subscribeToRefresh(throttledSend));
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'LSD.DebugInfoReq': {
|
|
50
|
+
sendToDevtools(Devtools.DebugInfoRes.make({
|
|
51
|
+
debugInfo: store.mainDbWrapper.debugInfo,
|
|
52
|
+
requestId,
|
|
53
|
+
channelId,
|
|
54
|
+
liveStoreVersion,
|
|
55
|
+
}));
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case 'LSD.DebugInfoHistorySubscribe': {
|
|
59
|
+
const buffer = [];
|
|
60
|
+
let hasStopped = false;
|
|
61
|
+
let rafHandle;
|
|
62
|
+
const tick = () => {
|
|
63
|
+
buffer.push(store.mainDbWrapper.debugInfo);
|
|
64
|
+
// NOTE this resets the debug info, so all other "readers" e.g. in other `requestAnimationFrame` loops,
|
|
65
|
+
// will get the empty debug info
|
|
66
|
+
// TODO We need to come up with a more graceful way to do store. Probably via a single global
|
|
67
|
+
// `requestAnimationFrame` loop that is passed in somehow.
|
|
68
|
+
store.mainDbWrapper.debugInfo = makeEmptyDebugInfo();
|
|
69
|
+
if (buffer.length > 10) {
|
|
70
|
+
sendToDevtools(Devtools.DebugInfoHistoryRes.make({
|
|
71
|
+
debugInfoHistory: buffer,
|
|
72
|
+
requestId,
|
|
73
|
+
channelId,
|
|
74
|
+
liveStoreVersion,
|
|
75
|
+
}));
|
|
76
|
+
buffer.length = 0;
|
|
77
|
+
}
|
|
78
|
+
if (hasStopped === false) {
|
|
79
|
+
rafHandle = requestAnimationFrame(tick);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
rafHandle = requestAnimationFrame(tick);
|
|
83
|
+
const unsub = () => {
|
|
84
|
+
hasStopped = true;
|
|
85
|
+
if (rafHandle !== undefined) {
|
|
86
|
+
cancelAnimationFrame(rafHandle);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
debugInfoHistorySubscriptions.set(requestId, unsub);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case 'LSD.DebugInfoHistoryUnsubscribe': {
|
|
93
|
+
debugInfoHistorySubscriptions.get(requestId)();
|
|
94
|
+
debugInfoHistorySubscriptions.delete(requestId);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case 'LSD.DebugInfoResetReq': {
|
|
98
|
+
store.mainDbWrapper.debugInfo.slowQueries.clear();
|
|
99
|
+
sendToDevtools(Devtools.DebugInfoResetRes.make({ requestId, channelId, liveStoreVersion }));
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case 'LSD.DebugInfoRerunQueryReq': {
|
|
103
|
+
const { queryStr, bindValues, queriedTables } = decodedMessage;
|
|
104
|
+
store.mainDbWrapper.select(queryStr, { bindValues, queriedTables, skipCache: true });
|
|
105
|
+
sendToDevtools(Devtools.DebugInfoRerunQueryRes.make({ requestId, channelId, liveStoreVersion }));
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'LSD.ReactivityGraphUnsubscribe': {
|
|
109
|
+
reactivityGraphSubcriptions.get(requestId)();
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'LSD.LiveQueriesSubscribe': {
|
|
113
|
+
const send = () => requestIdleCallback(() => sendToDevtools(Devtools.LiveQueriesRes.make({
|
|
114
|
+
liveQueries: [...store.activeQueries].map((q) => ({
|
|
115
|
+
_tag: q._tag,
|
|
116
|
+
id: q.id,
|
|
117
|
+
label: q.label,
|
|
118
|
+
runs: q.runs,
|
|
119
|
+
executionTimes: q.executionTimes.map((_) => Number(_.toString().slice(0, 5))),
|
|
120
|
+
lastestResult: q.results$.previousResult === NOT_REFRESHED_YET
|
|
121
|
+
? 'SYMBOL_NOT_REFRESHED_YET'
|
|
122
|
+
: q.results$.previousResult,
|
|
123
|
+
activeSubscriptions: Array.from(q.activeSubscriptions),
|
|
124
|
+
})),
|
|
125
|
+
requestId,
|
|
126
|
+
liveStoreVersion,
|
|
127
|
+
channelId,
|
|
128
|
+
})), { timeout: 500 });
|
|
129
|
+
send();
|
|
130
|
+
// Same as in the reactivity graph subscription case above, we need to throttle the updates
|
|
131
|
+
const throttledSend = throttle(send, 20);
|
|
132
|
+
liveQueriesSubscriptions.set(requestId, store.reactivityGraph.subscribeToRefresh(throttledSend));
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case 'LSD.LiveQueriesUnsubscribe': {
|
|
136
|
+
liveQueriesSubscriptions.get(requestId)();
|
|
137
|
+
liveQueriesSubscriptions.delete(requestId);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
// No default
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
yield* storePortChannel.listen.pipe(Stream.flatten(), Stream.tapSync((message) => onMessage(message)), Stream.runDrain, Effect.withSpan('LSD.devtools.onMessage'));
|
|
144
|
+
});
|
|
145
|
+
//# sourceMappingURL=store-devtools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-devtools.js","sourceRoot":"","sources":["../src/store-devtools.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { MainDatabaseWrapper } from './MainDatabaseWrapper.js';
|
|
|
8
8
|
import type { StackInfo } from './react/utils/stack-info.js';
|
|
9
9
|
import type { DebugRefreshReasonBase, Ref } from './reactive.js';
|
|
10
10
|
import type { LiveQuery, QueryContext, ReactivityGraph } from './reactiveQueries/base-class.js';
|
|
11
|
+
import { ReferenceCountedSet } from './utils/data-structures.js';
|
|
11
12
|
export type BaseGraphQLContext = {
|
|
12
13
|
queriedTables: Set<string>;
|
|
13
14
|
/** Needed by Pothos Otel plugin for resolver tracing to work */
|
|
@@ -170,14 +171,4 @@ export declare const createStorePromise: <TGraphQLContext extends BaseGraphQLCon
|
|
|
170
171
|
export declare const createStore: <TGraphQLContext extends BaseGraphQLContext, TSchema extends LiveStoreSchema = LiveStoreSchema>({ schema, graphQLOptions, otelOptions, adapter: adapterFactory, boot, reactivityGraph, batchUpdates, disableDevtools, onBootStatus, fiberSet, }: CreateStoreOptions<TGraphQLContext, TSchema> & {
|
|
171
172
|
fiberSet: FiberSet.FiberSet;
|
|
172
173
|
}) => Effect.Effect<Store<TGraphQLContext, TSchema>, UnexpectedError, Scope.Scope>;
|
|
173
|
-
declare class ReferenceCountedSet<T> {
|
|
174
|
-
private map;
|
|
175
|
-
constructor();
|
|
176
|
-
add: (key: T) => void;
|
|
177
|
-
remove: (key: T) => void;
|
|
178
|
-
has: (key: T) => boolean;
|
|
179
|
-
get size(): number;
|
|
180
|
-
[Symbol.iterator](): Generator<T, void, unknown>;
|
|
181
|
-
}
|
|
182
|
-
export {};
|
|
183
174
|
//# sourceMappingURL=store.d.ts.map
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,UAAU,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/dist/store.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Devtools, getExecArgsFromMutation,
|
|
2
|
-
import { makeMutationEventSchemaMemo } from '@livestore/common/schema';
|
|
3
|
-
import { assertNever, makeNoopTracer, shouldNeverHappen
|
|
1
|
+
import { Devtools, getExecArgsFromMutation, prepareBindValues, UnexpectedError } from '@livestore/common';
|
|
2
|
+
import { makeMutationEventSchemaMemo, SCHEMA_META_TABLE, SCHEMA_MUTATIONS_META_TABLE } from '@livestore/common/schema';
|
|
3
|
+
import { assertNever, makeNoopTracer, shouldNeverHappen } from '@livestore/utils';
|
|
4
4
|
import { cuid } from '@livestore/utils/cuid';
|
|
5
|
-
import { Effect, Exit, FiberSet, Inspectable, Layer, Logger, LogLevel, OtelTracer, Queue, Runtime, Schema, Scope, Stream, } from '@livestore/utils/effect';
|
|
5
|
+
import { BrowserChannel, Effect, Either, Exit, FiberSet, Inspectable, Layer, Logger, LogLevel, OtelTracer, Queue, Runtime, Schema, Scope, Stream, } from '@livestore/utils/effect';
|
|
6
6
|
import * as otel from '@opentelemetry/api';
|
|
7
7
|
import { globalReactivityGraph } from './global-state.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { MainDatabaseWrapper } from './MainDatabaseWrapper.js';
|
|
9
|
+
import { connectStoreToDevtools } from './store-devtools.js';
|
|
10
|
+
import { ReferenceCountedSet } from './utils/data-structures.js';
|
|
10
11
|
import { downloadBlob } from './utils/dev.js';
|
|
11
12
|
import { getDurationMsFromSpan } from './utils/otel.js';
|
|
12
13
|
let storeCount = 0;
|
|
@@ -33,6 +34,7 @@ export class Store extends Inspectable.Class {
|
|
|
33
34
|
/** RC-based set to see which queries are currently subscribed to */
|
|
34
35
|
activeQueries;
|
|
35
36
|
__mutationEventSchema;
|
|
37
|
+
// #region constructor
|
|
36
38
|
constructor({ adapter, schema, graphQLOptions, reactivityGraph, otelOptions, disableDevtools, __processedMutationIds, fiberSet, }) {
|
|
37
39
|
super();
|
|
38
40
|
this.mainDbWrapper = new MainDatabaseWrapper({ otel: otelOptions, db: adapter.mainDb });
|
|
@@ -61,8 +63,16 @@ export class Store extends Inspectable.Class {
|
|
|
61
63
|
mutationsSpanContext: otelMuationsSpanContext,
|
|
62
64
|
queriesSpanContext: otelQueriesSpanContext,
|
|
63
65
|
};
|
|
66
|
+
// TODO find a better way to detect if we're running LiveStore in the LiveStore devtools
|
|
67
|
+
// But for now this is a good enough approximation with little downsides
|
|
68
|
+
const isRunningInDevtools = disableDevtools === true;
|
|
64
69
|
// Need a set here since `schema.tables` might contain duplicates and some componentStateTables
|
|
65
|
-
const allTableNames = new Set(
|
|
70
|
+
const allTableNames = new Set(
|
|
71
|
+
// NOTE we're excluding the LiveStore schema and mutations tables as they are not user-facing
|
|
72
|
+
// unless LiveStore is running in the devtools
|
|
73
|
+
isRunningInDevtools
|
|
74
|
+
? this.schema.tables.keys()
|
|
75
|
+
: Array.from(this.schema.tables.keys()).filter((_) => _ !== SCHEMA_META_TABLE && _ !== SCHEMA_MUTATIONS_META_TABLE));
|
|
66
76
|
const existingTableRefs = new Map(Array.from(this.reactivityGraph.atoms.values())
|
|
67
77
|
.filter((_) => _._tag === 'ref' && _.label?.startsWith('tableRef:') === true)
|
|
68
78
|
.map((_) => [_.label.slice('tableRef:'.length), _]));
|
|
@@ -92,6 +102,7 @@ export class Store extends Inspectable.Class {
|
|
|
92
102
|
yield* Effect.never;
|
|
93
103
|
}).pipe(Effect.scoped, Effect.withSpan('LiveStore:store-constructor'), FiberSet.run(fiberSet), runEffectFork);
|
|
94
104
|
}
|
|
105
|
+
// #endregion constructor
|
|
95
106
|
static createStore = (storeOptions, parentSpan) => {
|
|
96
107
|
const ctx = otel.trace.setSpan(otel.context.active(), parentSpan);
|
|
97
108
|
return storeOptions.otelOptions.tracer.startActiveSpan('LiveStore:store-constructor', {}, ctx, (span) => {
|
|
@@ -138,6 +149,7 @@ export class Store extends Inspectable.Class {
|
|
|
138
149
|
destroy = async () => {
|
|
139
150
|
await FiberSet.clear(this.fiberSet).pipe(Effect.withSpan('Store:destroy'), runEffectPromise);
|
|
140
151
|
};
|
|
152
|
+
// #region mutate
|
|
141
153
|
mutate = (firstMutationOrTxnFnOrOptions, ...restMutations) => {
|
|
142
154
|
let mutationsEvents;
|
|
143
155
|
let options;
|
|
@@ -305,6 +317,7 @@ export class Store extends Inspectable.Class {
|
|
|
305
317
|
return { writeTables: allWriteTables, durationMs: durationMsTotal };
|
|
306
318
|
});
|
|
307
319
|
};
|
|
320
|
+
// #endregion mutate
|
|
308
321
|
/**
|
|
309
322
|
* Directly execute a SQL query on the Store.
|
|
310
323
|
* This should only be used for framework-internal purposes;
|
|
@@ -323,159 +336,33 @@ export class Store extends Inspectable.Class {
|
|
|
323
336
|
meta: { liveStoreRefType: 'table' },
|
|
324
337
|
});
|
|
325
338
|
// #region devtools
|
|
326
|
-
// TODO shutdown behaviour
|
|
327
339
|
bootDevtools = () => Effect.gen(this, function* () {
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
sendToDevtoolsContentscript(Devtools.DevtoolsWindowMessage.LoadIframe.make({}));
|
|
340
|
+
// const webBridgeBroadcastChannel = yield* Devtools.WebBridge.makeBroadcastChannel()
|
|
341
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias, unicorn/no-this-assignment
|
|
342
|
+
const store = this;
|
|
332
343
|
const channelId = this.adapter.coordinator.devtools.channelId;
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// console.log('storeMessagePort message', decodedMessage)
|
|
356
|
-
if (decodedMessage.channelId !== this.adapter.coordinator.devtools.channelId) {
|
|
357
|
-
// console.log(`Unknown message`, event)
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
const requestId = decodedMessage.requestId;
|
|
361
|
-
const sendToDevtools = (message) => storeMessagePort.postMessage(Schema.encodeSync(Devtools.MessageFromAppHostStore)(message));
|
|
362
|
-
const requestIdleCallback = window.requestIdleCallback ?? ((cb) => cb());
|
|
363
|
-
switch (decodedMessage._tag) {
|
|
364
|
-
case 'LSD.ReactivityGraphSubscribe': {
|
|
365
|
-
const includeResults = decodedMessage.includeResults;
|
|
366
|
-
const send = () =>
|
|
367
|
-
// In order to not add more work to the current tick, we use requestIdleCallback
|
|
368
|
-
// to send the reactivity graph updates to the devtools
|
|
369
|
-
requestIdleCallback(() => sendToDevtools(Devtools.ReactivityGraphRes.make({
|
|
370
|
-
reactivityGraph: this.reactivityGraph.getSnapshot({ includeResults }),
|
|
371
|
-
requestId,
|
|
372
|
-
liveStoreVersion,
|
|
373
|
-
})), { timeout: 500 });
|
|
374
|
-
send();
|
|
375
|
-
// In some cases, there can be A LOT of reactivity graph updates in a short period of time
|
|
376
|
-
// so we throttle the updates to avoid sending too much data
|
|
377
|
-
// This might need to be tweaked further and possibly be exposed to the user in some way.
|
|
378
|
-
const throttledSend = throttle(send, 20);
|
|
379
|
-
reactivityGraphSubcriptions.set(requestId, this.reactivityGraph.subscribeToRefresh(throttledSend));
|
|
380
|
-
break;
|
|
381
|
-
}
|
|
382
|
-
case 'LSD.DebugInfoReq': {
|
|
383
|
-
sendToDevtools(Devtools.DebugInfoRes.make({
|
|
384
|
-
debugInfo: this.mainDbWrapper.debugInfo,
|
|
385
|
-
requestId,
|
|
386
|
-
liveStoreVersion,
|
|
387
|
-
}));
|
|
388
|
-
break;
|
|
389
|
-
}
|
|
390
|
-
case 'LSD.DebugInfoHistorySubscribe': {
|
|
391
|
-
const buffer = [];
|
|
392
|
-
let hasStopped = false;
|
|
393
|
-
let rafHandle;
|
|
394
|
-
const tick = () => {
|
|
395
|
-
buffer.push(this.mainDbWrapper.debugInfo);
|
|
396
|
-
// NOTE this resets the debug info, so all other "readers" e.g. in other `requestAnimationFrame` loops,
|
|
397
|
-
// will get the empty debug info
|
|
398
|
-
// TODO We need to come up with a more graceful way to do this. Probably via a single global
|
|
399
|
-
// `requestAnimationFrame` loop that is passed in somehow.
|
|
400
|
-
this.mainDbWrapper.debugInfo = makeEmptyDebugInfo();
|
|
401
|
-
if (buffer.length > 10) {
|
|
402
|
-
sendToDevtools(Devtools.DebugInfoHistoryRes.make({
|
|
403
|
-
debugInfoHistory: buffer,
|
|
404
|
-
requestId,
|
|
405
|
-
liveStoreVersion,
|
|
406
|
-
}));
|
|
407
|
-
buffer.length = 0;
|
|
408
|
-
}
|
|
409
|
-
if (hasStopped === false) {
|
|
410
|
-
rafHandle = requestAnimationFrame(tick);
|
|
411
|
-
}
|
|
412
|
-
};
|
|
413
|
-
rafHandle = requestAnimationFrame(tick);
|
|
414
|
-
const unsub = () => {
|
|
415
|
-
hasStopped = true;
|
|
416
|
-
if (rafHandle !== undefined) {
|
|
417
|
-
cancelAnimationFrame(rafHandle);
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
debugInfoHistorySubscriptions.set(requestId, unsub);
|
|
421
|
-
break;
|
|
422
|
-
}
|
|
423
|
-
case 'LSD.DebugInfoHistoryUnsubscribe': {
|
|
424
|
-
debugInfoHistorySubscriptions.get(requestId)();
|
|
425
|
-
debugInfoHistorySubscriptions.delete(requestId);
|
|
426
|
-
break;
|
|
427
|
-
}
|
|
428
|
-
case 'LSD.DebugInfoResetReq': {
|
|
429
|
-
this.mainDbWrapper.debugInfo.slowQueries.clear();
|
|
430
|
-
sendToDevtools(Devtools.DebugInfoResetRes.make({ requestId, liveStoreVersion }));
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
case 'LSD.DebugInfoRerunQueryReq': {
|
|
434
|
-
const { queryStr, bindValues, queriedTables } = decodedMessage;
|
|
435
|
-
this.mainDbWrapper.select(queryStr, { bindValues, queriedTables, skipCache: true });
|
|
436
|
-
sendToDevtools(Devtools.DebugInfoRerunQueryRes.make({ requestId, liveStoreVersion }));
|
|
437
|
-
break;
|
|
438
|
-
}
|
|
439
|
-
case 'LSD.ReactivityGraphUnsubscribe': {
|
|
440
|
-
reactivityGraphSubcriptions.get(requestId)();
|
|
441
|
-
break;
|
|
442
|
-
}
|
|
443
|
-
case 'LSD.LiveQueriesSubscribe': {
|
|
444
|
-
const send = () => requestIdleCallback(() => sendToDevtools(Devtools.LiveQueriesRes.make({
|
|
445
|
-
liveQueries: [...this.activeQueries].map((q) => ({
|
|
446
|
-
_tag: q._tag,
|
|
447
|
-
id: q.id,
|
|
448
|
-
label: q.label,
|
|
449
|
-
runs: q.runs,
|
|
450
|
-
executionTimes: q.executionTimes.map((_) => Number(_.toString().slice(0, 5))),
|
|
451
|
-
lastestResult: q.results$.previousResult === NOT_REFRESHED_YET
|
|
452
|
-
? 'SYMBOL_NOT_REFRESHED_YET'
|
|
453
|
-
: q.results$.previousResult,
|
|
454
|
-
activeSubscriptions: Array.from(q.activeSubscriptions),
|
|
455
|
-
})),
|
|
456
|
-
requestId,
|
|
457
|
-
liveStoreVersion,
|
|
458
|
-
})), { timeout: 500 });
|
|
459
|
-
send();
|
|
460
|
-
// Same as in the reactivity graph subscription case above, we need to throttle the updates
|
|
461
|
-
const throttledSend = throttle(send, 20);
|
|
462
|
-
liveQueriesSubscriptions.set(requestId, this.reactivityGraph.subscribeToRefresh(throttledSend));
|
|
463
|
-
break;
|
|
464
|
-
}
|
|
465
|
-
case 'LSD.LiveQueriesUnsubscribe': {
|
|
466
|
-
liveQueriesSubscriptions.get(requestId)();
|
|
467
|
-
liveQueriesSubscriptions.delete(requestId);
|
|
468
|
-
break;
|
|
469
|
-
}
|
|
470
|
-
// No default
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
storeMessagePort.start();
|
|
474
|
-
}), Runtime.runFork(runtime));
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
});
|
|
478
|
-
sendToDevtoolsContentscript(Devtools.DevtoolsWindowMessage.StoreReady.make({ channelId }));
|
|
344
|
+
// Chrome extension bridge
|
|
345
|
+
{
|
|
346
|
+
const windowChannel = yield* BrowserChannel.windowChannel({
|
|
347
|
+
window,
|
|
348
|
+
listenSchema: Devtools.DevtoolsWindowMessage.MessageForStore,
|
|
349
|
+
sendSchema: Devtools.DevtoolsWindowMessage.MessageForContentscript,
|
|
350
|
+
});
|
|
351
|
+
yield* windowChannel.send(Devtools.DevtoolsWindowMessage.LoadIframe.make({}));
|
|
352
|
+
yield* windowChannel.listen.pipe(Stream.filterMap(Either.getRight), Stream.tap((message) => Effect.gen(function* () {
|
|
353
|
+
if (message._tag === 'LSD.WindowMessage.ContentscriptListening') {
|
|
354
|
+
// Send message to contentscript via window (which the contentscript iframe is listening to)
|
|
355
|
+
yield* windowChannel.send(Devtools.DevtoolsWindowMessage.StoreReady.make({ channelId }));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (message.channelId !== channelId)
|
|
359
|
+
return;
|
|
360
|
+
if (message._tag === 'LSD.WindowMessage.MessagePortForStore') {
|
|
361
|
+
yield* connectStoreToDevtools({ port: message.port, store });
|
|
362
|
+
}
|
|
363
|
+
})), Stream.runDrain, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
364
|
+
yield* windowChannel.send(Devtools.DevtoolsWindowMessage.StoreReady.make({ channelId }));
|
|
365
|
+
}
|
|
479
366
|
});
|
|
480
367
|
// #endregion devtools
|
|
481
368
|
__devDownloadDb = () => {
|
|
@@ -488,6 +375,7 @@ export class Store extends Inspectable.Class {
|
|
|
488
375
|
};
|
|
489
376
|
// TODO allow for graceful store reset without requiring a full page reload (which should also call .boot)
|
|
490
377
|
dangerouslyResetStorage = (mode) => this.adapter.coordinator.dangerouslyReset(mode).pipe(runEffectPromise);
|
|
378
|
+
// NOTE This is needed because when booting a Store via Effect it seems to call `toJSON` in the error path
|
|
491
379
|
toJSON = () => {
|
|
492
380
|
return {
|
|
493
381
|
_tag: 'Store',
|
|
@@ -607,37 +495,8 @@ export const createStore = ({ schema, graphQLOptions, otelOptions, adapter: adap
|
|
|
607
495
|
}), Effect.provide(TracingLive));
|
|
608
496
|
};
|
|
609
497
|
// #endregion createStore
|
|
610
|
-
// TODO
|
|
611
|
-
class ReferenceCountedSet {
|
|
612
|
-
map;
|
|
613
|
-
constructor() {
|
|
614
|
-
this.map = new Map();
|
|
615
|
-
}
|
|
616
|
-
add = (key) => {
|
|
617
|
-
const count = this.map.get(key) ?? 0;
|
|
618
|
-
this.map.set(key, count + 1);
|
|
619
|
-
};
|
|
620
|
-
remove = (key) => {
|
|
621
|
-
const count = this.map.get(key) ?? 0;
|
|
622
|
-
if (count === 1) {
|
|
623
|
-
this.map.delete(key);
|
|
624
|
-
}
|
|
625
|
-
else {
|
|
626
|
-
this.map.set(key, count - 1);
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
has = (key) => {
|
|
630
|
-
return this.map.has(key);
|
|
631
|
-
};
|
|
632
|
-
get size() {
|
|
633
|
-
return this.map.size;
|
|
634
|
-
}
|
|
635
|
-
*[Symbol.iterator]() {
|
|
636
|
-
for (const key of this.map.keys()) {
|
|
637
|
-
yield key;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
}
|
|
498
|
+
// TODO propagate runtime
|
|
641
499
|
const runEffectFork = (effect) => effect.pipe(Effect.tapCauseLogPretty, Effect.annotateLogs({ thread: 'window' }), Effect.provide(Logger.pretty), Logger.withMinimumLogLevel(LogLevel.Debug), Effect.runFork);
|
|
500
|
+
// TODO propagate runtime
|
|
642
501
|
const runEffectPromise = (effect) => effect.pipe(Effect.tapCauseLogPretty, Effect.annotateLogs({ thread: 'window' }), Effect.provide(Logger.pretty), Logger.withMinimumLogLevel(LogLevel.Debug), Effect.runPromise);
|
|
643
502
|
//# sourceMappingURL=store.js.map
|