@livestore/sync-cf 0.4.0-dev.1 → 0.4.0-dev.10

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 (136) hide show
  1. package/README.md +60 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cf-worker/do/durable-object.d.ts +45 -0
  4. package/dist/cf-worker/do/durable-object.d.ts.map +1 -0
  5. package/dist/cf-worker/do/durable-object.js +150 -0
  6. package/dist/cf-worker/do/durable-object.js.map +1 -0
  7. package/dist/cf-worker/do/layer.d.ts +34 -0
  8. package/dist/cf-worker/do/layer.d.ts.map +1 -0
  9. package/dist/cf-worker/do/layer.js +91 -0
  10. package/dist/cf-worker/do/layer.js.map +1 -0
  11. package/dist/cf-worker/do/pull.d.ts +6 -0
  12. package/dist/cf-worker/do/pull.d.ts.map +1 -0
  13. package/dist/cf-worker/do/pull.js +47 -0
  14. package/dist/cf-worker/do/pull.js.map +1 -0
  15. package/dist/cf-worker/do/push.d.ts +14 -0
  16. package/dist/cf-worker/do/push.d.ts.map +1 -0
  17. package/dist/cf-worker/do/push.js +131 -0
  18. package/dist/cf-worker/do/push.js.map +1 -0
  19. package/dist/cf-worker/{durable-object.d.ts → do/sqlite.d.ts} +77 -70
  20. package/dist/cf-worker/do/sqlite.d.ts.map +1 -0
  21. package/dist/cf-worker/do/sqlite.js +27 -0
  22. package/dist/cf-worker/do/sqlite.js.map +1 -0
  23. package/dist/cf-worker/do/sync-storage.d.ts +25 -0
  24. package/dist/cf-worker/do/sync-storage.d.ts.map +1 -0
  25. package/dist/cf-worker/do/sync-storage.js +190 -0
  26. package/dist/cf-worker/do/sync-storage.js.map +1 -0
  27. package/dist/cf-worker/do/transport/do-rpc-server.d.ts +9 -0
  28. package/dist/cf-worker/do/transport/do-rpc-server.d.ts.map +1 -0
  29. package/dist/cf-worker/do/transport/do-rpc-server.js +45 -0
  30. package/dist/cf-worker/do/transport/do-rpc-server.js.map +1 -0
  31. package/dist/cf-worker/do/transport/http-rpc-server.d.ts +7 -0
  32. package/dist/cf-worker/do/transport/http-rpc-server.d.ts.map +1 -0
  33. package/dist/cf-worker/do/transport/http-rpc-server.js +24 -0
  34. package/dist/cf-worker/do/transport/http-rpc-server.js.map +1 -0
  35. package/dist/cf-worker/do/transport/ws-rpc-server.d.ts +4 -0
  36. package/dist/cf-worker/do/transport/ws-rpc-server.d.ts.map +1 -0
  37. package/dist/cf-worker/do/transport/ws-rpc-server.js +21 -0
  38. package/dist/cf-worker/do/transport/ws-rpc-server.js.map +1 -0
  39. package/dist/cf-worker/mod.d.ts +4 -2
  40. package/dist/cf-worker/mod.d.ts.map +1 -1
  41. package/dist/cf-worker/mod.js +3 -2
  42. package/dist/cf-worker/mod.js.map +1 -1
  43. package/dist/cf-worker/shared.d.ts +147 -0
  44. package/dist/cf-worker/shared.d.ts.map +1 -0
  45. package/dist/cf-worker/shared.js +32 -0
  46. package/dist/cf-worker/shared.js.map +1 -0
  47. package/dist/cf-worker/worker.d.ts +45 -45
  48. package/dist/cf-worker/worker.d.ts.map +1 -1
  49. package/dist/cf-worker/worker.js +51 -39
  50. package/dist/cf-worker/worker.js.map +1 -1
  51. package/dist/client/mod.d.ts +4 -0
  52. package/dist/client/mod.d.ts.map +1 -0
  53. package/dist/client/mod.js +4 -0
  54. package/dist/client/mod.js.map +1 -0
  55. package/dist/client/transport/do-rpc-client.d.ts +40 -0
  56. package/dist/client/transport/do-rpc-client.d.ts.map +1 -0
  57. package/dist/client/transport/do-rpc-client.js +117 -0
  58. package/dist/client/transport/do-rpc-client.js.map +1 -0
  59. package/dist/client/transport/http-rpc-client.d.ts +43 -0
  60. package/dist/client/transport/http-rpc-client.d.ts.map +1 -0
  61. package/dist/client/transport/http-rpc-client.js +103 -0
  62. package/dist/client/transport/http-rpc-client.js.map +1 -0
  63. package/dist/client/transport/ws-rpc-client.d.ts +45 -0
  64. package/dist/client/transport/ws-rpc-client.d.ts.map +1 -0
  65. package/dist/client/transport/ws-rpc-client.js +108 -0
  66. package/dist/client/transport/ws-rpc-client.js.map +1 -0
  67. package/dist/common/constants.d.ts +7 -0
  68. package/dist/common/constants.d.ts.map +1 -0
  69. package/dist/common/constants.js +17 -0
  70. package/dist/common/constants.js.map +1 -0
  71. package/dist/common/do-rpc-schema.d.ts +76 -0
  72. package/dist/common/do-rpc-schema.d.ts.map +1 -0
  73. package/dist/common/do-rpc-schema.js +48 -0
  74. package/dist/common/do-rpc-schema.js.map +1 -0
  75. package/dist/common/http-rpc-schema.d.ts +58 -0
  76. package/dist/common/http-rpc-schema.d.ts.map +1 -0
  77. package/dist/common/http-rpc-schema.js +37 -0
  78. package/dist/common/http-rpc-schema.js.map +1 -0
  79. package/dist/common/mod.d.ts +8 -1
  80. package/dist/common/mod.d.ts.map +1 -1
  81. package/dist/common/mod.js +7 -1
  82. package/dist/common/mod.js.map +1 -1
  83. package/dist/common/{ws-message-types.d.ts → sync-message-types.d.ts} +119 -153
  84. package/dist/common/sync-message-types.d.ts.map +1 -0
  85. package/dist/common/sync-message-types.js +60 -0
  86. package/dist/common/sync-message-types.js.map +1 -0
  87. package/dist/common/ws-rpc-schema.d.ts +55 -0
  88. package/dist/common/ws-rpc-schema.d.ts.map +1 -0
  89. package/dist/common/ws-rpc-schema.js +32 -0
  90. package/dist/common/ws-rpc-schema.js.map +1 -0
  91. package/package.json +7 -8
  92. package/src/cf-worker/do/durable-object.ts +237 -0
  93. package/src/cf-worker/do/layer.ts +128 -0
  94. package/src/cf-worker/do/pull.ts +77 -0
  95. package/src/cf-worker/do/push.ts +205 -0
  96. package/src/cf-worker/do/sqlite.ts +28 -0
  97. package/src/cf-worker/do/sync-storage.ts +321 -0
  98. package/src/cf-worker/do/transport/do-rpc-server.ts +84 -0
  99. package/src/cf-worker/do/transport/http-rpc-server.ts +37 -0
  100. package/src/cf-worker/do/transport/ws-rpc-server.ts +34 -0
  101. package/src/cf-worker/mod.ts +4 -2
  102. package/src/cf-worker/shared.ts +112 -0
  103. package/src/cf-worker/worker.ts +91 -105
  104. package/src/client/mod.ts +3 -0
  105. package/src/client/transport/do-rpc-client.ts +191 -0
  106. package/src/client/transport/http-rpc-client.ts +225 -0
  107. package/src/client/transport/ws-rpc-client.ts +202 -0
  108. package/src/common/constants.ts +18 -0
  109. package/src/common/do-rpc-schema.ts +54 -0
  110. package/src/common/http-rpc-schema.ts +40 -0
  111. package/src/common/mod.ts +10 -1
  112. package/src/common/sync-message-types.ts +117 -0
  113. package/src/common/ws-rpc-schema.ts +36 -0
  114. package/dist/cf-worker/cf-types.d.ts +0 -2
  115. package/dist/cf-worker/cf-types.d.ts.map +0 -1
  116. package/dist/cf-worker/cf-types.js +0 -2
  117. package/dist/cf-worker/cf-types.js.map +0 -1
  118. package/dist/cf-worker/durable-object.d.ts.map +0 -1
  119. package/dist/cf-worker/durable-object.js +0 -317
  120. package/dist/cf-worker/durable-object.js.map +0 -1
  121. package/dist/common/ws-message-types.d.ts.map +0 -1
  122. package/dist/common/ws-message-types.js +0 -57
  123. package/dist/common/ws-message-types.js.map +0 -1
  124. package/dist/sync-impl/mod.d.ts +0 -2
  125. package/dist/sync-impl/mod.d.ts.map +0 -1
  126. package/dist/sync-impl/mod.js +0 -2
  127. package/dist/sync-impl/mod.js.map +0 -1
  128. package/dist/sync-impl/ws-impl.d.ts +0 -7
  129. package/dist/sync-impl/ws-impl.d.ts.map +0 -1
  130. package/dist/sync-impl/ws-impl.js +0 -175
  131. package/dist/sync-impl/ws-impl.js.map +0 -1
  132. package/src/cf-worker/cf-types.ts +0 -12
  133. package/src/cf-worker/durable-object.ts +0 -478
  134. package/src/common/ws-message-types.ts +0 -114
  135. package/src/sync-impl/mod.ts +0 -1
  136. package/src/sync-impl/ws-impl.ts +0 -274
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/http-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAChE,OAAO,KAAK,WAAW,MAAM,uCAAuC,CAAA;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAE,OAAO,EAAgC,EAAE,EAAE,CAChF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,YAAY,GAAG,kBAAkB,CAAA;IACvC,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IACnF,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IAExE,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC,UAAU,CAAC,OAA0B,CAAsC,CAClF,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;AAC/B,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAElD,MAAM,kBAAkB;AACtB,gCAAgC;AAChC,WAAW,CAAC,OAAO,CAAC;IAClB,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC;IAEnE,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAC1B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,CAAA;QACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;QAEpF,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC,CAAC;IAEJ,kBAAkB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;CACpE,CAAC,CAAC,IAAI,CACL,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,EACtE,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAC/C,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { Layer, RpcServer } from '@livestore/utils/effect';
2
+ import { type DoCtxInput } from '../layer.ts';
3
+ export declare const makeRpcServer: ({ doSelf, doOptions }: Omit<DoCtxInput, "from">) => Layer.Layer<never, never, RpcServer.Protocol>;
4
+ //# sourceMappingURL=ws-rpc-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/ws-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,EAAE,SAAS,EAAU,MAAM,yBAAyB,CAAA;AAEpF,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAIpD,eAAO,MAAM,aAAa,GAAI,uBAAuB,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,kDA0B5E,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { InvalidPullError, InvalidPushError } from '@livestore/common';
2
+ import { Effect, identity, Layer, RpcServer, Stream } from '@livestore/utils/effect';
3
+ import { SyncWsRpc } from "../../../common/ws-rpc-schema.js";
4
+ import { DoCtx } from "../layer.js";
5
+ import { makeEndingPullStream } from "../pull.js";
6
+ import { makePush } from "../push.js";
7
+ export const makeRpcServer = ({ doSelf, doOptions }) => {
8
+ // TODO implement admin requests
9
+ const handlersLayer = SyncWsRpc.toLayer({
10
+ 'SyncWsRpc.Pull': (req) => makeEndingPullStream(req, req.payload).pipe(
11
+ // Needed to keep the stream alive on the client side for phase 2 (i.e. not send the `Exit` stream RPC message)
12
+ req.live ? Stream.concat(Stream.never) : identity, Stream.provideLayer(DoCtx.Default({ doSelf, doOptions, from: { storeId: req.storeId } })), Stream.mapError((cause) => (cause._tag === 'InvalidPullError' ? cause : InvalidPullError.make({ cause })))),
13
+ 'SyncWsRpc.Push': (req) => Effect.gen(function* () {
14
+ const { doOptions, storeId, ctx, env } = yield* DoCtx;
15
+ const push = makePush({ options: doOptions, storeId, payload: req.payload, ctx, env });
16
+ return yield* push(req);
17
+ }).pipe(Effect.provide(DoCtx.Default({ doSelf, doOptions, from: { storeId: req.storeId } })), Effect.mapError((cause) => (cause._tag === 'InvalidPushError' ? cause : InvalidPushError.make({ cause }))), Effect.tapCauseLogPretty),
18
+ });
19
+ return RpcServer.layer(SyncWsRpc).pipe(Layer.provide(handlersLayer));
20
+ };
21
+ //# sourceMappingURL=ws-rpc-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/ws-rpc-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACpF,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAmB,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAA4B,EAAE,EAAE;IAC/E,gCAAgC;IAChC,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC;QACtC,gBAAgB,EAAE,CAAC,GAAG,EAAE,EAAE,CACxB,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI;QACzC,+GAA+G;QAC/G,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,EACjD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EACzF,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAE3G;QACH,gBAAgB,EAAE,CAAC,GAAG,EAAE,EAAE,CACxB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,CAAA;YAErD,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;YAEtF,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EACpF,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAC1G,MAAM,CAAC,iBAAiB,CACzB;KACJ,CAAC,CAAA;IAEF,OAAO,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;AACtE,CAAC,CAAA"}
@@ -1,4 +1,6 @@
1
- export * from './cf-types.ts';
2
- export * from './durable-object.ts';
1
+ export type { CfTypes } from '@livestore/common-cf';
2
+ export { CfDeclare } from '@livestore/common-cf/declare';
3
+ export * from './do/durable-object.ts';
4
+ export * from './shared.ts';
3
5
  export * from './worker.ts';
4
6
  //# sourceMappingURL=mod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/cf-worker/mod.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/cf-worker/mod.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,cAAc,wBAAwB,CAAA;AACtC,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
@@ -1,4 +1,5 @@
1
- export * from "./cf-types.js";
2
- export * from "./durable-object.js";
1
+ export { CfDeclare } from '@livestore/common-cf/declare';
2
+ export * from "./do/durable-object.js";
3
+ export * from "./shared.js";
3
4
  export * from "./worker.js";
4
5
  //# sourceMappingURL=mod.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/cf-worker/mod.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/cf-worker/mod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,cAAc,wBAAwB,CAAA;AACtC,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,147 @@
1
+ import type { InvalidPullError, InvalidPushError } from '@livestore/common';
2
+ import type { CfTypes } from '@livestore/common-cf';
3
+ import { Effect, Schema } from '@livestore/utils/effect';
4
+ import type { SearchParams } from '../common/mod.ts';
5
+ import { SyncMessage } from '../common/mod.ts';
6
+ export interface Env {
7
+ ADMIN_SECRET: string;
8
+ }
9
+ export type MakeDurableObjectClassOptions = {
10
+ onPush?: (message: SyncMessage.PushRequest, context: {
11
+ storeId: StoreId;
12
+ payload?: Schema.JsonValue;
13
+ }) => Effect.SyncOrPromiseOrEffect<void>;
14
+ onPushRes?: (message: SyncMessage.PushAck | InvalidPushError) => Effect.SyncOrPromiseOrEffect<void>;
15
+ onPull?: (message: SyncMessage.PullRequest, context: {
16
+ storeId: StoreId;
17
+ payload?: Schema.JsonValue;
18
+ }) => Effect.SyncOrPromiseOrEffect<void>;
19
+ onPullRes?: (message: SyncMessage.PullResponse | InvalidPullError) => Effect.SyncOrPromiseOrEffect<void>;
20
+ /**
21
+ * Storage engine for event persistence.
22
+ * - Default: `{ _tag: 'do-sqlite' }` (Durable Object SQLite)
23
+ * - D1: `{ _tag: 'd1', binding: string }` where `binding` is the D1 binding name in wrangler.toml.
24
+ *
25
+ * If omitted, the runtime defaults to DO SQLite. For backwards-compatibility, if an env binding named
26
+ * `DB` exists and looks like a D1Database, D1 will be used.
27
+ *
28
+ * Trade-offs:
29
+ * - DO SQLite: simpler deploy, data co-located with DO, not externally queryable
30
+ * - D1: centralized DB, inspectable with DB tools, extra network hop and JSON size limits
31
+ */
32
+ storage?: {
33
+ _tag: 'do-sqlite';
34
+ } | {
35
+ _tag: 'd1';
36
+ binding: string;
37
+ };
38
+ /**
39
+ * Enabled transports for sync backend
40
+ * - `http`: HTTP JSON-RPC
41
+ * - `ws`: WebSocket
42
+ * - `do-rpc`: Durable Object RPC calls (only works in combination with `@livestore/adapter-cf`)
43
+ *
44
+ * @default Set(['http', 'ws', 'do-rpc'])
45
+ */
46
+ enabledTransports?: Set<'http' | 'ws' | 'do-rpc'>;
47
+ otel?: {
48
+ baseUrl?: string;
49
+ serviceName?: string;
50
+ };
51
+ };
52
+ export type StoreId = string;
53
+ export type DurableObjectId = string;
54
+ /**
55
+ * Needs to be bumped when the storage format changes (e.g. eventlogTable schema changes)
56
+ *
57
+ * Changing this version number will lead to a "soft reset".
58
+ */
59
+ export declare const PERSISTENCE_FORMAT_VERSION = 7;
60
+ export declare const encodeOutgoingMessage: (a: {
61
+ readonly backendId: string;
62
+ readonly batch: readonly {
63
+ readonly metadata: import("effect/Option").Option<{
64
+ readonly createdAt: string;
65
+ readonly _tag: "SyncMessage.SyncMetadata";
66
+ }>;
67
+ readonly eventEncoded: {
68
+ readonly name: string;
69
+ readonly args: any;
70
+ readonly seqNum: any;
71
+ readonly parentSeqNum: any;
72
+ readonly clientId: string;
73
+ readonly sessionId: string;
74
+ };
75
+ }[];
76
+ readonly pageInfo: {
77
+ readonly _tag: "MoreUnknown";
78
+ } | {
79
+ readonly _tag: "MoreKnown";
80
+ readonly remaining: number;
81
+ } | {
82
+ readonly _tag: "NoMore";
83
+ };
84
+ } | {} | {
85
+ readonly _tag: "SyncMessage.Pong";
86
+ } | {
87
+ readonly _tag: "SyncMessage.AdminResetRoomResponse";
88
+ } | {
89
+ readonly info: {
90
+ readonly durableObjectId: string;
91
+ };
92
+ readonly _tag: "SyncMessage.AdminInfoResponse";
93
+ }, overrideOptions?: import("effect/SchemaAST").ParseOptions) => string;
94
+ export declare const encodeIncomingMessage: (a: {
95
+ readonly cursor: import("effect/Option").Option<{
96
+ readonly backendId: string;
97
+ readonly eventSequenceNumber: number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">;
98
+ }>;
99
+ } | {
100
+ readonly backendId: import("effect/Option").Option<string>;
101
+ readonly batch: readonly {
102
+ readonly name: string;
103
+ readonly args: any;
104
+ readonly seqNum: any;
105
+ readonly parentSeqNum: any;
106
+ readonly clientId: string;
107
+ readonly sessionId: string;
108
+ }[];
109
+ } | {
110
+ readonly _tag: "SyncMessage.Ping";
111
+ } | {
112
+ readonly _tag: "SyncMessage.AdminResetRoomRequest";
113
+ readonly adminSecret: string;
114
+ } | {
115
+ readonly _tag: "SyncMessage.AdminInfoRequest";
116
+ readonly adminSecret: string;
117
+ }, overrideOptions?: import("effect/SchemaAST").ParseOptions) => string;
118
+ /**
119
+ * Extracts the LiveStore sync search parameters from a request. Returns
120
+ * `undefined` when the request does not carry valid sync metadata so callers
121
+ * can fall back to custom routing.
122
+ */
123
+ export declare const matchSyncRequest: (request: CfTypes.Request) => SearchParams | undefined;
124
+ export type RpcSubscription = {
125
+ storeId: StoreId;
126
+ payload?: Schema.JsonValue;
127
+ subscribedAt: number;
128
+ /** Effect RPC request ID */
129
+ requestId: string;
130
+ callerContext: {
131
+ bindingName: string;
132
+ durableObjectId: string;
133
+ };
134
+ };
135
+ /**
136
+ * Durable Object interface supporting the DO RPC protocol for DO <> DO syncing.
137
+ */
138
+ export interface SyncBackendRpcInterface {
139
+ __DURABLE_OBJECT_BRAND: never;
140
+ rpc(payload: Uint8Array): Promise<Uint8Array | CfTypes.ReadableStream>;
141
+ }
142
+ export declare const WebSocketAttachmentSchema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
143
+ storeId: typeof Schema.String;
144
+ payload: Schema.optional<Schema.Schema<Schema.JsonValue, Schema.JsonValue, never>>;
145
+ pullRequestIds: Schema.Array$<typeof Schema.String>;
146
+ }>>;
147
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/cf-worker/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAa,MAAM,yBAAyB,CAAA;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAsB,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAElE,MAAM,WAAW,GAAG;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,CAAC,EAAE,CACP,OAAO,EAAE,WAAW,CAAC,WAAW,EAChC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,SAAS,CAAA;KAAE,KACtD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,GAAG,gBAAgB,KAAK,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;IACnG,MAAM,CAAC,EAAE,CACP,OAAO,EAAE,WAAW,CAAC,WAAW,EAChC,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,SAAS,CAAA;KAAE,KACtD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,YAAY,GAAG,gBAAgB,KAAK,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;IACxG;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IAEjE;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAA;IAEjD,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,OAAO,GAAG,MAAM,CAAA;AAC5B,MAAM,MAAM,eAAe,GAAG,MAAM,CAAA;AAEpC;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAE3C,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAA0E,CAAA;AAC5G,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;uEAA0E,CAAA;AAE5G;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,OAAO,CAAC,OAAO,KAAG,YAAY,GAAG,SAU1E,CAAA;AAGD,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,SAAS,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,sBAAsB,EAAE,KAAK,CAAA;IAC7B,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;CACvE;AAED,eAAO,MAAM,yBAAyB;;;;GAQrC,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { Effect, Schema, UrlParams } from '@livestore/utils/effect';
2
+ import { SearchParamsSchema, SyncMessage } from "../common/mod.js";
3
+ /**
4
+ * Needs to be bumped when the storage format changes (e.g. eventlogTable schema changes)
5
+ *
6
+ * Changing this version number will lead to a "soft reset".
7
+ */
8
+ export const PERSISTENCE_FORMAT_VERSION = 7;
9
+ export const encodeOutgoingMessage = Schema.encodeSync(Schema.parseJson(SyncMessage.BackendToClientMessage));
10
+ export const encodeIncomingMessage = Schema.encodeSync(Schema.parseJson(SyncMessage.ClientToBackendMessage));
11
+ /**
12
+ * Extracts the LiveStore sync search parameters from a request. Returns
13
+ * `undefined` when the request does not carry valid sync metadata so callers
14
+ * can fall back to custom routing.
15
+ */
16
+ export const matchSyncRequest = (request) => {
17
+ const url = new URL(request.url);
18
+ const urlParams = UrlParams.fromInput(url.searchParams);
19
+ const paramsResult = UrlParams.schemaStruct(SearchParamsSchema)(urlParams).pipe(Effect.option, Effect.runSync);
20
+ if (paramsResult._tag === 'None') {
21
+ return undefined;
22
+ }
23
+ return paramsResult.value;
24
+ };
25
+ export const WebSocketAttachmentSchema = Schema.parseJson(Schema.Struct({
26
+ // Same across all websocket connections
27
+ storeId: Schema.String,
28
+ // Different for each websocket connection
29
+ payload: Schema.optional(Schema.JsonValue),
30
+ pullRequestIds: Schema.Array(Schema.String),
31
+ }));
32
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/cf-worker/shared.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGnE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAkDlE;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAA;AAE3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAC5G,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAE5G;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAwB,EAA4B,EAAE;IACrF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IACvD,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;IAE9G,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACjC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,CAAA;AAC3B,CAAC,CAAA;AAuBD,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,SAAS,CACvD,MAAM,CAAC,MAAM,CAAC;IACZ,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;IAC1C,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;CAC5C,CAAC,CACH,CAAA"}
@@ -1,34 +1,19 @@
1
- import type * as CfWorker from '@cloudflare/workers-types';
1
+ import type { HelperTypes } from '@livestore/common-cf';
2
2
  import type { Schema } from '@livestore/utils/effect';
3
- import type { Env } from './durable-object.ts';
4
- export declare namespace HelperTypes {
5
- type AnyDON = CfWorker.DurableObjectNamespace<undefined>;
6
- type DOKeys<T> = {
7
- [K in keyof T]-?: T[K] extends AnyDON ? K : never;
8
- }[keyof T];
9
- type NonBuiltins<T> = Omit<T, keyof Env>;
10
- /**
11
- * Helper type to extract DurableObject keys from Env to give consumer type safety.
12
- *
13
- * @example
14
- * ```ts
15
- * type PlatformEnv = {
16
- * DB: D1Database
17
- * ADMIN_TOKEN: string
18
- * WEBSOCKET_SERVER: DurableObjectNamespace<WebSocketServer>
19
- * }
20
- * export default makeWorker<PlatformEnv>({
21
- * durableObject: { name: "WEBSOCKET_SERVER" },
22
- * // ^ (property) name?: "WEBSOCKET_SERVER" | undefined
23
- * });
24
- */
25
- export type ExtractDurableObjectKeys<TEnv = Env> = DOKeys<NonBuiltins<TEnv>> extends never ? string : DOKeys<NonBuiltins<TEnv>>;
26
- export {};
27
- }
28
- export type CFWorker<TEnv extends Env = Env, _T extends CfWorker.Rpc.DurableObjectBranded | undefined = undefined> = {
29
- fetch: <CFHostMetada = unknown>(request: CfWorker.Request<CFHostMetada>, env: TEnv, ctx: CfWorker.ExecutionContext) => Promise<CfWorker.Response>;
3
+ import type { CfTypes, SearchParams } from '../common/mod.ts';
4
+ import { type Env } from './shared.ts';
5
+ export type CFWorker<TEnv extends Env = Env, _T extends CfTypes.Rpc.DurableObjectBranded | undefined = undefined> = {
6
+ fetch: <CFHostMetada = unknown>(request: CfTypes.Request<CFHostMetada>, env: TEnv, ctx: CfTypes.ExecutionContext) => Promise<CfTypes.Response>;
30
7
  };
8
+ /**
9
+ * Options accepted by {@link makeWorker}. The Durable Object binding has to be
10
+ * supplied explicitly so we never fall back to deprecated defaults when Cloudflare config changes.
11
+ */
31
12
  export type MakeWorkerOptions<TEnv extends Env = Env> = {
13
+ /**
14
+ * Binding name of the sync Durable Object declared in wrangler config.
15
+ */
16
+ syncBackendBinding: HelperTypes.ExtractDurableObjectKeys<TEnv>;
32
17
  /**
33
18
  * Validates the payload during WebSocket connection establishment.
34
19
  * Note: This runs only at connection time, not for individual push events.
@@ -39,18 +24,17 @@ export type MakeWorkerOptions<TEnv extends Env = Env> = {
39
24
  }) => void | Promise<void>;
40
25
  /** @default false */
41
26
  enableCORS?: boolean;
42
- durableObject?: {
43
- /**
44
- * Needs to match the binding name from the wrangler config
45
- *
46
- * @default 'WEBSOCKET_SERVER'
47
- */
48
- name?: HelperTypes.ExtractDurableObjectKeys<TEnv>;
49
- };
50
27
  };
51
- export declare const makeWorker: <TEnv extends Env = Env, TDurableObjectRpc extends CfWorker.Rpc.DurableObjectBranded | undefined = undefined>(options?: MakeWorkerOptions<TEnv>) => CFWorker<TEnv, TDurableObjectRpc>;
52
28
  /**
53
- * Handles `/websocket` endpoint.
29
+ * Produces a Cloudflare Worker `fetch` handler that delegates sync traffic to the
30
+ * Durable Object identified by `syncBackendBinding`.
31
+ *
32
+ * For more complex setups prefer implementing a custom `fetch` and call {@link handleSyncRequest}
33
+ * from the branch that handles LiveStore sync requests.
34
+ */
35
+ export declare const makeWorker: <TEnv extends Env = Env, TDurableObjectRpc extends CfTypes.Rpc.DurableObjectBranded | undefined = undefined>(options: MakeWorkerOptions<TEnv>) => CFWorker<TEnv, TDurableObjectRpc>;
36
+ /**
37
+ * Handles LiveStore sync requests (e.g. with search params `?storeId=...&transport=...`).
54
38
  *
55
39
  * @example
56
40
  * ```ts
@@ -63,23 +47,39 @@ export declare const makeWorker: <TEnv extends Env = Env, TDurableObjectRpc exte
63
47
  *
64
48
  * export default {
65
49
  * fetch: async (request, env, ctx) => {
66
- * if (request.url.endsWith('/websocket')) {
67
- * return handleWebSocket(request, env, ctx, { headers: {}, validatePayload })
50
+ * const searchParams = matchSyncRequest(request)
51
+ *
52
+ * // Is LiveStore sync request
53
+ * if (searchParams !== undefined) {
54
+ * return handleSyncRequest({
55
+ * request,
56
+ * searchParams,
57
+ * env,
58
+ * ctx,
59
+ * syncBackendBinding: 'SYNC_BACKEND_DO',
60
+ * headers: {},
61
+ * validatePayload,
62
+ * })
68
63
  * }
69
64
  *
70
65
  * return new Response('Invalid path', { status: 400 })
71
- * return new Response('Invalid path', { status: 400 })
72
66
  * }
73
67
  * }
74
68
  * ```
75
69
  *
76
70
  * @throws {UnexpectedError} If the payload is invalid
77
71
  */
78
- export declare const handleWebSocket: <TEnv extends Env = Env, TDurableObjectRpc extends CfWorker.Rpc.DurableObjectBranded | undefined = undefined, CFHostMetada = unknown>(request: CfWorker.Request<CFHostMetada>, env: TEnv, _ctx: CfWorker.ExecutionContext, options?: {
79
- headers?: CfWorker.HeadersInit;
80
- durableObject?: MakeWorkerOptions<TEnv>["durableObject"];
72
+ export declare const handleSyncRequest: <TEnv extends Env = Env, TDurableObjectRpc extends CfTypes.Rpc.DurableObjectBranded | undefined = undefined, CFHostMetada = unknown>({ request, searchParams: { storeId, payload, transport }, env, syncBackendBinding, headers, validatePayload, }: {
73
+ request: CfTypes.Request<CFHostMetada>;
74
+ searchParams: SearchParams;
75
+ env: TEnv;
76
+ /** Only there for type-level reasons */
77
+ ctx: CfTypes.ExecutionContext;
78
+ /** Binding name of the sync backend Durable Object */
79
+ syncBackendBinding: MakeWorkerOptions<TEnv>["syncBackendBinding"];
80
+ headers?: CfTypes.HeadersInit | undefined;
81
81
  validatePayload?: (payload: Schema.JsonValue | undefined, context: {
82
82
  storeId: string;
83
83
  }) => void | Promise<void>;
84
- }) => Promise<CfWorker.Response>;
84
+ }) => Promise<CfTypes.Response>;
85
85
  //# sourceMappingURL=worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/cf-worker/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/cf-worker/worker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAErD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE7D,OAAO,EAAE,KAAK,GAAG,EAAoB,MAAM,aAAa,CAAA;AAMxD,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,GAAG,GAAG,GAAG,EAAE,EAAE,SAAS,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,SAAS,GAAG,SAAS,IAAI;IAClH,KAAK,EAAE,CAAC,YAAY,GAAG,OAAO,EAC5B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EACtC,GAAG,EAAE,IAAI,EACT,GAAG,EAAE,OAAO,CAAC,gBAAgB,KAC1B,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,GAAG,GAAG,GAAG,IAAI;IACtD;;OAEG;IACH,kBAAkB,EAAE,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAA;IAC9D;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/G,qBAAqB;IACrB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GACrB,IAAI,SAAS,GAAG,GAAG,GAAG,EACtB,iBAAiB,SAAS,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,SAAS,GAAG,SAAS,EAElF,SAAS,iBAAiB,CAAC,IAAI,CAAC,KAC/B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAuDlC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,iBAAiB,GAC5B,IAAI,SAAS,GAAG,GAAG,GAAG,EACtB,iBAAiB,SAAS,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,SAAS,GAAG,SAAS,EAClF,YAAY,GAAG,OAAO,EACtB,gHAOC;IACD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IACtC,YAAY,EAAE,YAAY,CAAA;IAC1B,GAAG,EAAE,IAAI,CAAA;IACT,wCAAwC;IACxC,GAAG,EAAE,OAAO,CAAC,gBAAgB,CAAA;IAC7B,sDAAsD;IACtD,kBAAkB,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAA;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,GAAG,SAAS,CAAA;IACzC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChH,KAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAyC0B,CAAA"}
@@ -1,17 +1,17 @@
1
1
  import { UnexpectedError } from '@livestore/common';
2
- import { Effect, UrlParams } from '@livestore/utils/effect';
3
- import { SearchParamsSchema } from "../common/mod.js";
4
- export const makeWorker = (options = {}) => {
2
+ import { Effect } from '@livestore/utils/effect';
3
+ import { matchSyncRequest } from "./shared.js";
4
+ /**
5
+ * Produces a Cloudflare Worker `fetch` handler that delegates sync traffic to the
6
+ * Durable Object identified by `syncBackendBinding`.
7
+ *
8
+ * For more complex setups prefer implementing a custom `fetch` and call {@link handleSyncRequest}
9
+ * from the branch that handles LiveStore sync requests.
10
+ */
11
+ export const makeWorker = (options) => {
5
12
  return {
6
13
  fetch: async (request, env, _ctx) => {
7
14
  const url = new URL(request.url);
8
- await new Promise((resolve) => setTimeout(resolve, 500));
9
- if (request.method === 'GET' && url.pathname === '/') {
10
- return new Response('Info: WebSocket sync backend endpoint for @livestore/sync-cf.', {
11
- status: 200,
12
- headers: { 'Content-Type': 'text/plain' },
13
- });
14
- }
15
15
  const corsHeaders = options.enableCORS
16
16
  ? {
17
17
  'Access-Control-Allow-Origin': '*',
@@ -25,11 +25,24 @@ export const makeWorker = (options = {}) => {
25
25
  headers: corsHeaders,
26
26
  });
27
27
  }
28
- if (url.pathname.endsWith('/websocket')) {
29
- return handleWebSocket(request, env, _ctx, {
28
+ const searchParams = matchSyncRequest(request);
29
+ // Check if this is a sync request first, before showing info message
30
+ if (searchParams !== undefined) {
31
+ return handleSyncRequest({
32
+ request,
33
+ searchParams,
34
+ env,
35
+ ctx: _ctx,
36
+ syncBackendBinding: options.syncBackendBinding,
30
37
  headers: corsHeaders,
31
38
  validatePayload: options.validatePayload,
32
- durableObject: options.durableObject,
39
+ });
40
+ }
41
+ // Only show info message for GET requests to / without sync parameters
42
+ if (request.method === 'GET' && url.pathname === '/') {
43
+ return new Response('Info: Sync backend endpoint for @livestore/sync-cf.', {
44
+ status: 200,
45
+ headers: { 'Content-Type': 'text/plain' },
33
46
  });
34
47
  }
35
48
  console.error('Invalid path', url.pathname);
@@ -45,7 +58,7 @@ export const makeWorker = (options = {}) => {
45
58
  };
46
59
  };
47
60
  /**
48
- * Handles `/websocket` endpoint.
61
+ * Handles LiveStore sync requests (e.g. with search params `?storeId=...&transport=...`).
49
62
  *
50
63
  * @example
51
64
  * ```ts
@@ -58,54 +71,53 @@ export const makeWorker = (options = {}) => {
58
71
  *
59
72
  * export default {
60
73
  * fetch: async (request, env, ctx) => {
61
- * if (request.url.endsWith('/websocket')) {
62
- * return handleWebSocket(request, env, ctx, { headers: {}, validatePayload })
74
+ * const searchParams = matchSyncRequest(request)
75
+ *
76
+ * // Is LiveStore sync request
77
+ * if (searchParams !== undefined) {
78
+ * return handleSyncRequest({
79
+ * request,
80
+ * searchParams,
81
+ * env,
82
+ * ctx,
83
+ * syncBackendBinding: 'SYNC_BACKEND_DO',
84
+ * headers: {},
85
+ * validatePayload,
86
+ * })
63
87
  * }
64
88
  *
65
89
  * return new Response('Invalid path', { status: 400 })
66
- * return new Response('Invalid path', { status: 400 })
67
90
  * }
68
91
  * }
69
92
  * ```
70
93
  *
71
94
  * @throws {UnexpectedError} If the payload is invalid
72
95
  */
73
- export const handleWebSocket = (request, env, _ctx, options = {}) => Effect.gen(function* () {
74
- const url = new URL(request.url);
75
- const urlParams = UrlParams.fromInput(url.searchParams);
76
- const paramsResult = yield* UrlParams.schemaStruct(SearchParamsSchema)(urlParams).pipe(Effect.either);
77
- if (paramsResult._tag === 'Left') {
78
- return new Response(`Invalid search params: ${paramsResult.left.toString()}`, {
79
- status: 500,
80
- headers: options?.headers,
81
- });
82
- }
83
- const { storeId, payload } = paramsResult.right;
84
- if (options.validatePayload !== undefined) {
85
- const result = yield* Effect.promise(async () => options.validatePayload(payload, { storeId })).pipe(UnexpectedError.mapToUnexpectedError, Effect.either);
96
+ export const handleSyncRequest = ({ request, searchParams: { storeId, payload, transport }, env, syncBackendBinding, headers, validatePayload, }) => Effect.gen(function* () {
97
+ if (validatePayload !== undefined) {
98
+ const result = yield* Effect.promise(async () => validatePayload(payload, { storeId })).pipe(UnexpectedError.mapToUnexpectedError, Effect.either);
86
99
  if (result._tag === 'Left') {
87
100
  console.error('Invalid payload', result.left);
88
- return new Response(result.left.toString(), { status: 400, headers: options.headers });
101
+ return new Response(result.left.toString(), { status: 400, headers });
89
102
  }
90
103
  }
91
- const durableObjectName = options.durableObject?.name ?? 'WEBSOCKET_SERVER';
92
- if (!(durableObjectName in env)) {
93
- return new Response(`Failed dependency: Required Durable Object binding '${durableObjectName}' not available`, {
104
+ if (!(syncBackendBinding in env)) {
105
+ return new Response(`Failed dependency: Required Durable Object binding '${syncBackendBinding}' not available`, {
94
106
  status: 424,
95
- headers: options.headers,
107
+ headers,
96
108
  });
97
109
  }
98
- const durableObjectNamespace = env[durableObjectName];
110
+ const durableObjectNamespace = env[syncBackendBinding];
99
111
  const id = durableObjectNamespace.idFromName(storeId);
100
112
  const durableObject = durableObjectNamespace.get(id);
113
+ // Handle WebSocket upgrade request
101
114
  const upgradeHeader = request.headers.get('Upgrade');
102
- if (!upgradeHeader || upgradeHeader !== 'websocket') {
115
+ if (transport === 'ws' && (upgradeHeader === null || upgradeHeader !== 'websocket')) {
103
116
  return new Response('Durable Object expected Upgrade: websocket', {
104
117
  status: 426,
105
- headers: options?.headers,
118
+ headers,
106
119
  });
107
120
  }
108
- // Cloudflare Durable Object type clashing with lib.dom Response type, which is why we need the casts here.
109
121
  return yield* Effect.promise(() => durableObject.fetch(request));
110
122
  }).pipe(Effect.tapCauseLogPretty, Effect.runPromise);
111
123
  //# sourceMappingURL=worker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/cf-worker/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/cf-worker/worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './transport/do-rpc-client.ts';
2
+ export * from './transport/http-rpc-client.ts';
3
+ export * from './transport/ws-rpc-client.ts';
4
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/client/mod.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,8BAA8B,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from "./transport/do-rpc-client.js";
2
+ export * from "./transport/http-rpc-client.js";
3
+ export * from "./transport/ws-rpc-client.js";
4
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/client/mod.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,8BAA8B,CAAA"}
@@ -0,0 +1,40 @@
1
+ import { SyncBackend } from '@livestore/common';
2
+ import { type CfTypes } from '@livestore/common-cf';
3
+ import type { SyncBackendRpcInterface } from '../../cf-worker/shared.ts';
4
+ import type { SyncMetadata } from '../../common/sync-message-types.ts';
5
+ export interface SyncBackendRpcStub extends CfTypes.DurableObjectStub, SyncBackendRpcInterface {
6
+ }
7
+ export interface DoRpcSyncOptions {
8
+ /** Durable Object stub that implements the SyncDoRpc interface */
9
+ syncBackendStub: SyncBackendRpcStub;
10
+ /** Information about this DurableObject instance so the Sync DO instance can call back to this instance */
11
+ durableObjectContext: {
12
+ /** See `wrangler.toml` for the binding name */
13
+ bindingName: string;
14
+ /** `state.id.toString()` in the DO */
15
+ durableObjectId: string;
16
+ };
17
+ }
18
+ /**
19
+ * Creates a sync backend that uses Durable Object RPC to communicate with the sync backend.
20
+ *
21
+ * Used internally by `@livestore/adapter-cf` to connect to the sync backend.
22
+ */
23
+ export declare const makeDoRpcSync: ({ syncBackendStub, durableObjectContext }: DoRpcSyncOptions) => SyncBackend.SyncBackendConstructor<SyncMetadata>;
24
+ /**
25
+ *
26
+ * ```ts
27
+ * import { DurableObject } from 'cloudflare:workers'
28
+ * import { ClientDoWithRpcCallback } from '@livestore/common-cf'
29
+ *
30
+ * export class MyDurableObject extends DurableObject implements ClientDoWithRpcCallback {
31
+ * // ...
32
+ *
33
+ * async syncUpdateRpc(payload: RpcMessage.ResponseChunkEncoded) {
34
+ * return handleSyncUpdateRpc(payload)
35
+ * }
36
+ * }
37
+ * ```
38
+ */
39
+ export declare const handleSyncUpdateRpc: (payload: unknown) => Promise<void>;
40
+ //# sourceMappingURL=do-rpc-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do-rpc-client.d.ts","sourceRoot":"","sources":["../../../src/client/transport/do-rpc-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,WAAW,EAAmB,MAAM,mBAAmB,CAAA;AAEpG,OAAO,EAAE,KAAK,OAAO,EAA8B,MAAM,sBAAsB,CAAA;AAe/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAIxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAEtE,MAAM,WAAW,kBAAmB,SAAQ,OAAO,CAAC,iBAAiB,EAAE,uBAAuB;CAAG;AAMjG,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,eAAe,EAAE,kBAAkB,CAAA;IACnC,2GAA2G;IAC3G,oBAAoB,EAAE;QACpB,+CAA+C;QAC/C,WAAW,EAAE,MAAM,CAAA;QACnB,sCAAsC;QACtC,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACvB,2CAA2C,gBAAgB,KAAG,WAAW,CAAC,sBAAsB,CAAC,YAAY,CA2GnD,CAAA;AAE7D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,OAAO,kBAckD,CAAA"}