@livestore/adapter-web 0.0.0-snapshot-f6ec49b1a18859aad769f0a0d8edf8bae231ed07 → 0.0.0-snapshot-2ef046b02334f52613d31dbe06af53487685edc0

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 (29) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/in-memory/in-memory-adapter.d.ts.map +1 -1
  3. package/dist/in-memory/in-memory-adapter.js +1 -2
  4. package/dist/in-memory/in-memory-adapter.js.map +1 -1
  5. package/dist/web-worker/client-session/persisted-adapter.d.ts +9 -0
  6. package/dist/web-worker/client-session/persisted-adapter.d.ts.map +1 -1
  7. package/dist/web-worker/client-session/persisted-adapter.js +7 -32
  8. package/dist/web-worker/client-session/persisted-adapter.js.map +1 -1
  9. package/dist/web-worker/common/persisted-sqlite.d.ts +2 -1
  10. package/dist/web-worker/common/persisted-sqlite.d.ts.map +1 -1
  11. package/dist/web-worker/common/persisted-sqlite.js +6 -4
  12. package/dist/web-worker/common/persisted-sqlite.js.map +1 -1
  13. package/dist/web-worker/common/worker-schema.d.ts +6 -18
  14. package/dist/web-worker/common/worker-schema.d.ts.map +1 -1
  15. package/dist/web-worker/common/worker-schema.js +6 -13
  16. package/dist/web-worker/common/worker-schema.js.map +1 -1
  17. package/dist/web-worker/leader-worker/make-leader-worker.d.ts.map +1 -1
  18. package/dist/web-worker/leader-worker/make-leader-worker.js +8 -16
  19. package/dist/web-worker/leader-worker/make-leader-worker.js.map +1 -1
  20. package/dist/web-worker/shared-worker/make-shared-worker.d.ts.map +1 -1
  21. package/dist/web-worker/shared-worker/make-shared-worker.js +32 -54
  22. package/dist/web-worker/shared-worker/make-shared-worker.js.map +1 -1
  23. package/package.json +6 -6
  24. package/src/in-memory/in-memory-adapter.ts +1 -4
  25. package/src/web-worker/client-session/persisted-adapter.ts +21 -48
  26. package/src/web-worker/common/persisted-sqlite.ts +12 -4
  27. package/src/web-worker/common/worker-schema.ts +6 -22
  28. package/src/web-worker/leader-worker/make-leader-worker.ts +10 -24
  29. package/src/web-worker/shared-worker/make-shared-worker.ts +40 -80
@@ -1,12 +1,11 @@
1
1
  import { UnexpectedError } from '@livestore/common'
2
2
  import { connectViaWorker } from '@livestore/devtools-web-common/web-channel'
3
- import * as WebMeshWorker from '@livestore/devtools-web-common/worker'
3
+ import * as WebmeshWorker from '@livestore/devtools-web-common/worker'
4
4
  import { isDevEnv, isNotUndefined, LS_DEV } from '@livestore/utils'
5
5
  import {
6
6
  BrowserWorker,
7
7
  BrowserWorkerRunner,
8
8
  Deferred,
9
- Duration,
10
9
  Effect,
11
10
  Exit,
12
11
  FetchHttpClient,
@@ -15,7 +14,6 @@ import {
15
14
  Logger,
16
15
  LogLevel,
17
16
  ParseResult,
18
- Queue,
19
17
  Ref,
20
18
  Schema,
21
19
  Scope,
@@ -65,6 +63,7 @@ const makeWorkerRunner = Effect.gen(function* () {
65
63
  Effect.andThen((worker) => worker.executeEffect(req) as Effect.Effect<unknown, unknown, never>),
66
64
  // Effect.tap((_) => Effect.log(`forwardRequest: ${req._tag}`, _)),
67
65
  // Effect.tapError((cause) => Effect.logError(`forwardRequest err: ${req._tag}`, cause)),
66
+ Effect.interruptible,
68
67
  Effect.logWarnIfTakesLongerThan({
69
68
  label: `@livestore/adapter-web:shared-worker:forwardRequest:${req._tag}`,
70
69
  duration: 500,
@@ -80,57 +79,35 @@ const makeWorkerRunner = Effect.gen(function* () {
80
79
  Effect.tapCauseLogPretty,
81
80
  ) as any
82
81
 
83
- // const forwardRequestStream = <TReq extends WorkerSchema.DedicatedWorkerInner.Request>(
84
- // req: TReq,
85
- // ): TReq extends Serializable.WithResult<infer A, infer _I, infer _E, infer _EI, infer _R>
86
- // ? Stream.Stream<A, UnexpectedError, never>
87
- // : never =>
88
- // waitForWorker.pipe(
89
- // Effect.logBefore(`forwardRequestStream: ${req._tag}`),
90
- // Effect.andThen((worker) => worker.execute(req) as Stream.Stream<unknown, unknown, never>),
91
- // Effect.interruptible,
92
- // UnexpectedError.mapToUnexpectedError,
93
- // Effect.tapCauseLogPretty,
94
- // Stream.unwrap,
95
- // Stream.ensuring(Effect.logDebug(`shutting down stream for ${req._tag}`)),
96
- // UnexpectedError.mapToUnexpectedErrorStream,
97
- // ) as any
98
-
99
- // TODO bring back the `forwardRequestStream` impl above. Needs debugging with Tim Smart
100
- // It seems the in-progress streams are not being closed properly if the worker is closed (e.g. by closing the leader tab)
101
82
  const forwardRequestStream = <TReq extends WorkerSchema.LeaderWorkerInner.Request>(
102
83
  req: TReq,
103
84
  ): TReq extends Schema.WithResult<infer A, infer _I, infer _E, infer _EI, infer _R>
104
85
  ? Stream.Stream<A, UnexpectedError, never>
105
86
  : never =>
106
87
  Effect.gen(function* () {
88
+ yield* Effect.logDebug(`forwardRequestStream: ${req._tag}`)
107
89
  const { worker, scope } = yield* SubscriptionRef.waitUntil(leaderWorkerContextSubRef, isNotUndefined)
108
- const queue = yield* Queue.unbounded()
90
+ const stream = worker.execute(req) as Stream.Stream<unknown, unknown, never>
109
91
 
110
- yield* Scope.addFinalizer(scope, Queue.shutdown(queue))
92
+ // It seems the request stream is not automatically interrupted when the scope shuts down
93
+ // so we need to manually interrupt it when the scope shuts down
94
+ const shutdownDeferred = yield* Deferred.make<void>()
95
+ yield* Scope.addFinalizer(scope, Deferred.succeed(shutdownDeferred, undefined))
111
96
 
112
- const workerStream = worker.execute(req) as Stream.Stream<unknown, unknown, never>
97
+ // Here we're creating an empty stream that will finish when the scope shuts down
98
+ const scopeShutdownStream = Effect.gen(function* () {
99
+ yield* shutdownDeferred
100
+ return Stream.empty
101
+ }).pipe(Stream.unwrap)
113
102
 
114
- yield* workerStream.pipe(
115
- Stream.tap((_) => Queue.offer(queue, _)),
116
- Stream.runDrain,
117
- Effect.interruptible,
118
- Effect.forkIn(scope),
119
- )
120
-
121
- return Stream.fromQueue(queue)
103
+ return Stream.merge(stream, scopeShutdownStream, { haltStrategy: 'either' })
122
104
  }).pipe(
105
+ Effect.interruptible,
123
106
  UnexpectedError.mapToUnexpectedError,
124
107
  Effect.tapCauseLogPretty,
125
108
  Stream.unwrap,
126
- Stream.mapError((cause) =>
127
- Schema.is(UnexpectedError)(cause)
128
- ? cause
129
- : ParseResult.isParseError(cause) || Schema.is(WorkerError.WorkerError)(cause)
130
- ? new UnexpectedError({ cause })
131
- : cause,
132
- ),
133
- // Stream.ensuring(Effect.logDebug(`shutting down stream for ${req._tag}`)),
109
+ Stream.ensuring(Effect.logDebug(`shutting down stream for ${req._tag}`)),
110
+ UnexpectedError.mapToUnexpectedErrorStream,
134
111
  ) as any
135
112
 
136
113
  const resetCurrentWorkerCtx = Effect.gen(function* () {
@@ -142,14 +119,10 @@ const makeWorkerRunner = Effect.gen(function* () {
142
119
  yield* Effect.yieldNow()
143
120
 
144
121
  yield* Scope.close(prevWorker.scope, Exit.void).pipe(
145
- // TODO there still seem to be scenarios where it takes longer than 1 second which is leading to problems
146
- Effect.timeout(Duration.seconds(1)),
147
122
  Effect.logWarnIfTakesLongerThan({
148
123
  label: '@livestore/adapter-web:shared-worker:close-previous-worker',
149
124
  duration: 500,
150
125
  }),
151
- // Effect.catchTag('TimeoutException', () => Scope.close(prevWorker.scope, Exit.fail('boom'))),
152
- Effect.ignoreLogged,
153
126
  )
154
127
  }
155
128
  }).pipe(Effect.withSpan('@livestore/adapter-web:shared-worker:resetCurrentWorkerCtx'))
@@ -208,26 +181,6 @@ const makeWorkerRunner = Effect.gen(function* () {
208
181
 
209
182
  const scope = yield* Scope.make()
210
183
 
211
- const workerDeferred = yield* Deferred.make<
212
- Worker.SerializedWorkerPool<WorkerSchema.LeaderWorkerInner.Request>,
213
- UnexpectedError
214
- >()
215
- // TODO we could also keep the pool instance around to re-use it by removing the previous worker and adding a new one
216
- yield* Worker.makePoolSerialized<WorkerSchema.LeaderWorkerInner.Request>({
217
- size: 1,
218
- concurrency: 100,
219
- initialMessage: () => initialMessagePayload.initialMessage,
220
- }).pipe(
221
- Effect.tap((worker) => Deferred.succeed(workerDeferred, worker)),
222
- Effect.provide(BrowserWorker.layer(() => port)),
223
- Effect.catchAllCause((cause) => new UnexpectedError({ cause })),
224
- Effect.tapError((cause) => Deferred.fail(workerDeferred, cause)),
225
- Effect.withSpan('@livestore/adapter-web:shared-worker:makeWorkerProxyFromPort'),
226
- Effect.tapCauseLogPretty,
227
- Scope.extend(scope),
228
- Effect.forkIn(scope),
229
- )
230
-
231
184
  yield* Effect.gen(function* () {
232
185
  const shutdownChannel = yield* makeShutdownChannel(initialMessagePayload.initialMessage.storeId)
233
186
 
@@ -235,22 +188,32 @@ const makeWorkerRunner = Effect.gen(function* () {
235
188
  Stream.flatten(),
236
189
  Stream.tap(() => reset),
237
190
  Stream.runDrain,
191
+ Effect.tapCauseLogPretty,
192
+ Effect.forkScoped,
238
193
  )
239
- }).pipe(Effect.tapCauseLogPretty, Scope.extend(scope), Effect.forkIn(scope))
240
194
 
241
- const worker = yield* workerDeferred
195
+ const workerLayer = yield* Layer.build(BrowserWorker.layer(() => port))
242
196
 
243
- // Prepare the web mesh connection for leader worker to be able to connect to the devtools
244
- const { node } = yield* WebMeshWorker.CacheService
245
- const { storeId, clientId } = initialMessagePayload.initialMessage
197
+ const worker = yield* Worker.makePoolSerialized<WorkerSchema.LeaderWorkerInner.Request>({
198
+ size: 1,
199
+ concurrency: 100,
200
+ initialMessage: () => initialMessagePayload.initialMessage,
201
+ }).pipe(
202
+ Effect.provide(workerLayer),
203
+ Effect.withSpan('@livestore/adapter-web:shared-worker:makeWorkerProxyFromPort'),
204
+ )
246
205
 
247
- yield* connectViaWorker({ node, worker, target: `leader-${storeId}-${clientId}` }).pipe(
248
- Effect.tapCauseLogPretty,
249
- Scope.extend(scope),
250
- Effect.forkIn(scope),
251
- )
206
+ // Prepare the web mesh connection for leader worker to be able to connect to the devtools
207
+ const { node } = yield* WebmeshWorker.CacheService
208
+ const { storeId, clientId } = initialMessagePayload.initialMessage
252
209
 
253
- yield* SubscriptionRef.set(leaderWorkerContextSubRef, { worker, scope })
210
+ yield* connectViaWorker({ node, worker, target: `leader-${storeId}-${clientId}` }).pipe(
211
+ Effect.tapCauseLogPretty,
212
+ Effect.forkScoped,
213
+ )
214
+
215
+ yield* SubscriptionRef.set(leaderWorkerContextSubRef, { worker, scope })
216
+ }).pipe(Effect.tapCauseLogPretty, Scope.extend(scope), Effect.forkIn(scope))
254
217
  }).pipe(
255
218
  Effect.withSpan('@livestore/adapter-web:shared-worker:updateMessagePort'),
256
219
  UnexpectedError.mapToUnexpectedError,
@@ -267,14 +230,11 @@ const makeWorkerRunner = Effect.gen(function* () {
267
230
  Setup: forwardRequest,
268
231
  GetLeaderSyncState: forwardRequest,
269
232
  GetLeaderHead: forwardRequest,
270
- NetworkStatusStream: forwardRequestStream,
271
233
  Shutdown: forwardRequest,
272
234
  ExtraDevtoolsMessage: forwardRequest,
273
235
 
274
236
  // Accept devtools connections (from leader and client sessions)
275
- 'DevtoolsWebCommon.CreateConnection': WebMeshWorker.CreateConnection,
276
-
277
- // ...devtoolsWebBridge.handlers,
237
+ 'DevtoolsWebCommon.CreateConnection': WebmeshWorker.CreateConnection,
278
238
  })
279
239
  }).pipe(Layer.unwrapScoped)
280
240
 
@@ -288,7 +248,7 @@ export const makeWorker = () => {
288
248
  Effect.annotateLogs({ thread: self.name }),
289
249
  Effect.provide(Logger.prettyWithThread(self.name)),
290
250
  Effect.provide(FetchHttpClient.layer),
291
- Effect.provide(WebMeshWorker.CacheService.layer({ nodeName: 'shared-worker' })),
251
+ Effect.provide(WebmeshWorker.CacheService.layer({ nodeName: 'shared-worker' })),
292
252
  LS_DEV ? TaskTracing.withAsyncTaggingTracing((name) => (console as any).createTask(name)) : identity,
293
253
  // TODO remove type-cast (currently needed to silence a tsc bug)
294
254
  (_) => _ as any as Effect.Effect<void, any>,