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

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 +53 -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 +94 -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
@@ -1,16 +1,10 @@
1
1
  import { State } from '@livestore/common/schema';
2
- import { Effect, Option, Schema } from '@livestore/utils/effect';
3
- import { WSMessage } from '../common/mod.ts';
4
- import type * as CfWorker from './cf-types.ts';
5
- export interface Env {
6
- DB: CfWorker.D1Database;
7
- ADMIN_SECRET: string;
8
- }
9
- export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"eventlog_$PERSISTENCE_FORMAT_VERSION_$storeId", {
2
+ import { Schema } from '@livestore/utils/effect';
3
+ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"eventlog_7_$storeId", {
10
4
  readonly seqNum: {
11
5
  columnType: "integer";
12
6
  schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
13
- default: Option.None<never>;
7
+ default: import("effect/Option").None<never>;
14
8
  nullable: false;
15
9
  primaryKey: true;
16
10
  autoIncrement: false;
@@ -18,7 +12,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
18
12
  readonly parentSeqNum: {
19
13
  columnType: "integer";
20
14
  schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
21
- default: Option.None<never>;
15
+ default: import("effect/Option").None<never>;
22
16
  nullable: false;
23
17
  primaryKey: false;
24
18
  autoIncrement: false;
@@ -26,7 +20,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
26
20
  readonly name: {
27
21
  columnType: "text";
28
22
  schema: Schema.Schema<string, string, never>;
29
- default: Option.None<never>;
23
+ default: import("effect/Option").None<never>;
30
24
  nullable: false;
31
25
  primaryKey: false;
32
26
  autoIncrement: false;
@@ -34,7 +28,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
34
28
  readonly args: {
35
29
  columnType: "text";
36
30
  schema: Schema.Schema<any, string | null, never>;
37
- default: Option.None<never>;
31
+ default: import("effect/Option").None<never>;
38
32
  nullable: true;
39
33
  primaryKey: false;
40
34
  autoIncrement: false;
@@ -43,7 +37,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
43
37
  readonly createdAt: {
44
38
  columnType: "text";
45
39
  schema: Schema.Schema<string, string, never>;
46
- default: Option.None<never>;
40
+ default: import("effect/Option").None<never>;
47
41
  nullable: false;
48
42
  primaryKey: false;
49
43
  autoIncrement: false;
@@ -51,7 +45,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
51
45
  readonly clientId: {
52
46
  columnType: "text";
53
47
  schema: Schema.Schema<string, string, never>;
54
- default: Option.None<never>;
48
+ default: import("effect/Option").None<never>;
55
49
  nullable: false;
56
50
  primaryKey: false;
57
51
  autoIncrement: false;
@@ -59,7 +53,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
59
53
  readonly sessionId: {
60
54
  columnType: "text";
61
55
  schema: Schema.Schema<string, string, never>;
62
- default: Option.None<never>;
56
+ default: import("effect/Option").None<never>;
63
57
  nullable: false;
64
58
  primaryKey: false;
65
59
  autoIncrement: false;
@@ -68,7 +62,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
68
62
  readonly seqNum: {
69
63
  columnType: "integer";
70
64
  schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
71
- default: Option.None<never>;
65
+ default: import("effect/Option").None<never>;
72
66
  nullable: false;
73
67
  primaryKey: true;
74
68
  autoIncrement: false;
@@ -76,7 +70,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
76
70
  readonly parentSeqNum: {
77
71
  columnType: "integer";
78
72
  schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
79
- default: Option.None<never>;
73
+ default: import("effect/Option").None<never>;
80
74
  nullable: false;
81
75
  primaryKey: false;
82
76
  autoIncrement: false;
@@ -84,7 +78,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
84
78
  readonly name: {
85
79
  columnType: "text";
86
80
  schema: Schema.Schema<string, string, never>;
87
- default: Option.None<never>;
81
+ default: import("effect/Option").None<never>;
88
82
  nullable: false;
89
83
  primaryKey: false;
90
84
  autoIncrement: false;
@@ -92,7 +86,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
92
86
  readonly args: {
93
87
  columnType: "text";
94
88
  schema: Schema.Schema<any, string | null, never>;
95
- default: Option.None<never>;
89
+ default: import("effect/Option").None<never>;
96
90
  nullable: true;
97
91
  primaryKey: false;
98
92
  autoIncrement: false;
@@ -101,7 +95,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
101
95
  readonly createdAt: {
102
96
  columnType: "text";
103
97
  schema: Schema.Schema<string, string, never>;
104
- default: Option.None<never>;
98
+ default: import("effect/Option").None<never>;
105
99
  nullable: false;
106
100
  primaryKey: false;
107
101
  autoIncrement: false;
@@ -109,7 +103,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
109
103
  readonly clientId: {
110
104
  columnType: "text";
111
105
  schema: Schema.Schema<string, string, never>;
112
- default: Option.None<never>;
106
+ default: import("effect/Option").None<never>;
113
107
  nullable: false;
114
108
  primaryKey: false;
115
109
  autoIncrement: false;
@@ -117,7 +111,7 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
117
111
  readonly sessionId: {
118
112
  columnType: "text";
119
113
  schema: Schema.Schema<string, string, never>;
120
- default: Option.None<never>;
114
+ default: import("effect/Option").None<never>;
121
115
  nullable: false;
122
116
  primaryKey: false;
123
117
  autoIncrement: false;
@@ -139,51 +133,64 @@ export declare const eventlogTable: State.SQLite.TableDef<State.SQLite.SqliteTab
139
133
  readonly clientId: string;
140
134
  readonly sessionId: string;
141
135
  }, never>>;
142
- export declare const PULL_CHUNK_SIZE = 100;
143
- /**
144
- * Needs to be bumped when the storage format changes (e.g. eventlogTable schema changes)
145
- *
146
- * Changing this version number will lead to a "soft reset".
147
- */
148
- export declare const PERSISTENCE_FORMAT_VERSION = 7;
149
- export type MakeDurableObjectClassOptions = {
150
- onPush?: (message: WSMessage.PushReq, context: {
151
- storeId: string;
152
- payload?: Schema.JsonValue;
153
- }) => Effect.Effect<void> | Promise<void>;
154
- onPushRes?: (message: WSMessage.PushAck | WSMessage.Error) => Effect.Effect<void> | Promise<void>;
155
- onPull?: (message: WSMessage.PullReq, context: {
156
- storeId: string;
157
- payload?: Schema.JsonValue;
158
- }) => Effect.Effect<void> | Promise<void>;
159
- onPullRes?: (message: WSMessage.PullRes | WSMessage.Error) => Effect.Effect<void> | Promise<void>;
160
- };
161
- export type MakeDurableObjectClass = (options?: MakeDurableObjectClassOptions) => {
162
- new (ctx: CfWorker.DurableObjectState, env: Env): CfWorker.DurableObject;
163
- };
164
- /**
165
- * Creates a Durable Object class for handling WebSocket-based sync.
166
- *
167
- * Example:
168
- * ```ts
169
- * // In your Cloudflare Worker file
170
- * import { makeDurableObject } from '@livestore/sync-cf/cf-worker'
171
- *
172
- * export class WebSocketServer extends makeDurableObject({
173
- * onPush: async (message) => {
174
- * console.log('onPush', message.batch)
175
- * },
176
- * onPull: async (message) => {
177
- * console.log('onPull', message)
178
- * },
179
- * }) {}
180
- * ```
181
- *
182
- * ```toml
183
- * # wrangler.toml
184
- * [new_classes]
185
- * WebSocketServer = "src/websocket-server.ts"
186
- * ```
187
- */
188
- export declare const makeDurableObject: MakeDurableObjectClass;
189
- //# sourceMappingURL=durable-object.d.ts.map
136
+ /** Will only ever have one row per durable object. */
137
+ export declare const contextTable: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"context_7", {
138
+ readonly storeId: {
139
+ columnType: "text";
140
+ schema: Schema.Schema<string, string, never>;
141
+ default: import("effect/Option").None<never>;
142
+ nullable: false;
143
+ primaryKey: true;
144
+ autoIncrement: false;
145
+ };
146
+ readonly currentHead: {
147
+ columnType: "integer";
148
+ schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
149
+ default: import("effect/Option").None<never>;
150
+ nullable: false;
151
+ primaryKey: false;
152
+ autoIncrement: false;
153
+ };
154
+ readonly backendId: {
155
+ columnType: "text";
156
+ schema: Schema.Schema<string, string, never>;
157
+ default: import("effect/Option").None<never>;
158
+ nullable: false;
159
+ primaryKey: false;
160
+ autoIncrement: false;
161
+ };
162
+ }>, State.SQLite.WithDefaults<{
163
+ readonly storeId: {
164
+ columnType: "text";
165
+ schema: Schema.Schema<string, string, never>;
166
+ default: import("effect/Option").None<never>;
167
+ nullable: false;
168
+ primaryKey: true;
169
+ autoIncrement: false;
170
+ };
171
+ readonly currentHead: {
172
+ columnType: "integer";
173
+ schema: Schema.Schema<number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">, number, never>;
174
+ default: import("effect/Option").None<never>;
175
+ nullable: false;
176
+ primaryKey: false;
177
+ autoIncrement: false;
178
+ };
179
+ readonly backendId: {
180
+ columnType: "text";
181
+ schema: Schema.Schema<string, string, never>;
182
+ default: import("effect/Option").None<never>;
183
+ nullable: false;
184
+ primaryKey: false;
185
+ autoIncrement: false;
186
+ };
187
+ }>, Schema.Schema<{
188
+ readonly storeId: string;
189
+ readonly currentHead: number & import("effect/Brand").Brand<"GlobalEventSequenceNumber">;
190
+ readonly backendId: string;
191
+ }, {
192
+ readonly storeId: string;
193
+ readonly currentHead: number;
194
+ readonly backendId: string;
195
+ }, never>>;
196
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/cf-worker/do/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAGhD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAQtB,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAnE,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAKrE,CAAA;AAEF,sDAAsD;AACtD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOvB,CAAA"}
@@ -0,0 +1,27 @@
1
+ import { EventSequenceNumber, State } from '@livestore/common/schema';
2
+ import { Schema } from '@livestore/utils/effect';
3
+ import { PERSISTENCE_FORMAT_VERSION } from "../shared.js";
4
+ export const eventlogTable = State.SQLite.table({
5
+ // NOTE actual table name is determined at runtime to use proper storeId
6
+ name: `eventlog_${PERSISTENCE_FORMAT_VERSION}_$storeId`,
7
+ columns: {
8
+ seqNum: State.SQLite.integer({ primaryKey: true, schema: EventSequenceNumber.GlobalEventSequenceNumber }),
9
+ parentSeqNum: State.SQLite.integer({ schema: EventSequenceNumber.GlobalEventSequenceNumber }),
10
+ name: State.SQLite.text({}),
11
+ args: State.SQLite.text({ schema: Schema.parseJson(Schema.Any), nullable: true }),
12
+ /** ISO date format. Currently only used for debugging purposes. */
13
+ createdAt: State.SQLite.text({}),
14
+ clientId: State.SQLite.text({}),
15
+ sessionId: State.SQLite.text({}),
16
+ },
17
+ });
18
+ /** Will only ever have one row per durable object. */
19
+ export const contextTable = State.SQLite.table({
20
+ name: `context_${PERSISTENCE_FORMAT_VERSION}`,
21
+ columns: {
22
+ storeId: State.SQLite.text({ primaryKey: true }),
23
+ currentHead: State.SQLite.integer({ schema: EventSequenceNumber.GlobalEventSequenceNumber }),
24
+ backendId: State.SQLite.text({}),
25
+ },
26
+ });
27
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/cf-worker/do/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AAEzD,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;IAC9C,wEAAwE;IACxE,IAAI,EAAE,YAAY,0BAA0B,WAAW;IACvD,OAAO,EAAE;QACP,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,CAAC,yBAAyB,EAAE,CAAC;QACzG,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,yBAAyB,EAAE,CAAC;QAC7F,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACjF,mEAAmE;QACnE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;KACjC;CACF,CAAC,CAAA;AAEF,sDAAsD;AACtD,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;IAC7C,IAAI,EAAE,WAAW,0BAA0B,EAAE;IAC7C,OAAO,EAAE;QACP,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAChD,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,yBAAyB,EAAE,CAAC;QAC5F,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;KACjC;CACF,CAAC,CAAA"}
@@ -0,0 +1,25 @@
1
+ import { UnexpectedError } from '@livestore/common';
2
+ import type { LiveStoreEvent } from '@livestore/common/schema';
3
+ import type { CfTypes } from '@livestore/common-cf';
4
+ import { Effect, Option, Stream } from '@livestore/utils/effect';
5
+ import { SyncMetadata } from '../../common/sync-message-types.ts';
6
+ import { type StoreId } from '../shared.ts';
7
+ export type SyncStorage = {
8
+ dbName: string;
9
+ getEvents: (cursor: number | undefined) => Effect.Effect<{
10
+ total: number;
11
+ stream: Stream.Stream<{
12
+ eventEncoded: LiveStoreEvent.AnyEncodedGlobal;
13
+ metadata: Option.Option<SyncMetadata>;
14
+ }, UnexpectedError>;
15
+ }, UnexpectedError>;
16
+ appendEvents: (batch: ReadonlyArray<LiveStoreEvent.AnyEncodedGlobal>, createdAt: string) => Effect.Effect<void, UnexpectedError>;
17
+ resetStore: Effect.Effect<void, UnexpectedError>;
18
+ };
19
+ export declare const makeStorage: (ctx: CfTypes.DurableObjectState, storeId: StoreId, engine: {
20
+ _tag: "d1";
21
+ db: CfTypes.D1Database;
22
+ } | {
23
+ _tag: "do-sqlite";
24
+ }) => SyncStorage;
25
+ //# sourceMappingURL=sync-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-storage.d.ts","sourceRoot":"","sources":["../../../src/cf-worker/do/sync-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAS,MAAM,EAAE,MAAM,EAAU,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACjE,OAAO,EAA8B,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAGvE,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC,MAAM,CACtD;QACE,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAC,MAAM,CACnB;YAAE,YAAY,EAAE,cAAc,CAAC,gBAAgB,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;SAAE,EACxF,eAAe,CAChB,CAAA;KACF,EACD,eAAe,CAChB,CAAA;IACD,YAAY,EAAE,CACZ,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,gBAAgB,CAAC,EACrD,SAAS,EAAE,MAAM,KACd,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAA;IACzC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAA;CACjD,CAAA;AAED,eAAO,MAAM,WAAW,GACtB,KAAK,OAAO,CAAC,kBAAkB,EAC/B,SAAS,OAAO,EAChB,QAAQ;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,KACrE,WA+RF,CAAA"}
@@ -0,0 +1,190 @@
1
+ import { UnexpectedError } from '@livestore/common';
2
+ import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect';
3
+ import { SyncMetadata } from "../../common/sync-message-types.js";
4
+ import { PERSISTENCE_FORMAT_VERSION } from "../shared.js";
5
+ import { eventlogTable } from "./sqlite.js";
6
+ export const makeStorage = (ctx, storeId, engine) => {
7
+ const dbName = `eventlog_${PERSISTENCE_FORMAT_VERSION}_${toValidTableName(storeId)}`;
8
+ const execDb = (cb) => Effect.tryPromise({
9
+ try: () => cb(engine._tag === 'd1' ? engine.db : undefined),
10
+ catch: (error) => new UnexpectedError({ cause: error, payload: { dbName } }),
11
+ }).pipe(Effect.map((_) => _.results), Effect.withSpan('@livestore/sync-cf:durable-object:execDb'));
12
+ // Cloudflare's D1 HTTP endpoint rejects JSON responses once they exceed ~1MB.
13
+ // Keep individual SELECT batches comfortably below that threshold so we can
14
+ // serve large histories without tripping the limit.
15
+ const D1_MAX_JSON_RESPONSE_BYTES = 1_000_000;
16
+ const D1_RESPONSE_SAFETY_MARGIN_BYTES = 64 * 1024;
17
+ const D1_TARGET_RESPONSE_BYTES = D1_MAX_JSON_RESPONSE_BYTES - D1_RESPONSE_SAFETY_MARGIN_BYTES;
18
+ const D1_INITIAL_PAGE_SIZE = 256;
19
+ const D1_MIN_PAGE_SIZE = 1;
20
+ const decodeEventlogRows = Schema.decodeUnknownSync(Schema.Array(eventlogTable.rowSchema));
21
+ const textEncoder = new TextEncoder();
22
+ const decreaseLimit = (limit) => Math.max(D1_MIN_PAGE_SIZE, Math.floor(limit / 2));
23
+ const increaseLimit = (limit) => Math.min(D1_INITIAL_PAGE_SIZE, limit * 2);
24
+ const computeNextLimit = (limit, encodedSize) => {
25
+ if (encodedSize > D1_TARGET_RESPONSE_BYTES && limit > D1_MIN_PAGE_SIZE) {
26
+ const next = decreaseLimit(limit);
27
+ return next === limit ? limit : next;
28
+ }
29
+ if (encodedSize < D1_TARGET_RESPONSE_BYTES / 2 && limit < D1_INITIAL_PAGE_SIZE) {
30
+ const next = increaseLimit(limit);
31
+ return next === limit ? limit : next;
32
+ }
33
+ return limit;
34
+ };
35
+ const getEventsD1 = (cursor) => Effect.gen(function* () {
36
+ const countStatement = cursor === undefined
37
+ ? `SELECT COUNT(*) as total FROM ${dbName}`
38
+ : `SELECT COUNT(*) as total FROM ${dbName} WHERE seqNum > ?`;
39
+ const countRows = yield* execDb((db) => {
40
+ const prepared = db.prepare(countStatement);
41
+ return cursor === undefined ? prepared.all() : prepared.bind(cursor).all();
42
+ });
43
+ const total = Number(countRows[0]?.total ?? 0);
44
+ const initialState = { cursor, limit: D1_INITIAL_PAGE_SIZE };
45
+ const fetchPage = (state) => Effect.gen(function* () {
46
+ const statement = state.cursor === undefined
47
+ ? `SELECT * FROM ${dbName} ORDER BY seqNum ASC LIMIT ?`
48
+ : `SELECT * FROM ${dbName} WHERE seqNum > ? ORDER BY seqNum ASC LIMIT ?`;
49
+ const rawEvents = yield* execDb((db) => {
50
+ const prepared = db.prepare(statement);
51
+ return state.cursor === undefined
52
+ ? prepared.bind(state.limit).all()
53
+ : prepared.bind(state.cursor, state.limit).all();
54
+ });
55
+ if (rawEvents.length === 0) {
56
+ return Option.none();
57
+ }
58
+ const encodedSize = textEncoder.encode(JSON.stringify(rawEvents)).byteLength;
59
+ if (encodedSize > D1_TARGET_RESPONSE_BYTES && state.limit > D1_MIN_PAGE_SIZE) {
60
+ const nextLimit = decreaseLimit(state.limit);
61
+ if (nextLimit !== state.limit) {
62
+ return yield* fetchPage({ cursor: state.cursor, limit: nextLimit });
63
+ }
64
+ }
65
+ const decodedRows = Chunk.fromIterable(decodeEventlogRows(rawEvents));
66
+ const eventsChunk = Chunk.map(decodedRows, ({ createdAt, ...eventEncoded }) => ({
67
+ eventEncoded,
68
+ metadata: Option.some(SyncMetadata.make({ createdAt })),
69
+ }));
70
+ const lastSeqNum = Chunk.unsafeLast(decodedRows).seqNum;
71
+ const nextState = { cursor: lastSeqNum, limit: computeNextLimit(state.limit, encodedSize) };
72
+ return Option.some([eventsChunk, nextState]);
73
+ });
74
+ const stream = Stream.unfoldChunkEffect(initialState, fetchPage);
75
+ return { total, stream };
76
+ }).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/sync-cf:durable-object:getEvents', {
77
+ attributes: { dbName, cursor, engine: engine._tag },
78
+ }));
79
+ const appendEventsD1 = (batch, createdAt) => Effect.gen(function* () {
80
+ // If there are no events, do nothing.
81
+ if (batch.length === 0)
82
+ return;
83
+ // CF D1 limits:
84
+ // Maximum bound parameters per query 100, Maximum arguments per SQL function 32
85
+ // Thus we need to split the batch into chunks of max (100/7=)14 events each.
86
+ const CHUNK_SIZE = 14;
87
+ for (let i = 0; i < batch.length; i += CHUNK_SIZE) {
88
+ const chunk = batch.slice(i, i + CHUNK_SIZE);
89
+ // Create a list of placeholders ("(?, ?, ?, ?, ?, ?, ?)"), corresponding to each event.
90
+ const valuesPlaceholders = chunk.map(() => '(?, ?, ?, ?, ?, ?, ?)').join(', ');
91
+ const sql = `INSERT INTO ${dbName} (seqNum, parentSeqNum, args, name, createdAt, clientId, sessionId) VALUES ${valuesPlaceholders}`;
92
+ // Flatten the event properties into a parameters array.
93
+ const params = chunk.flatMap((event) => [
94
+ event.seqNum,
95
+ event.parentSeqNum,
96
+ event.args === undefined ? null : JSON.stringify(event.args),
97
+ event.name,
98
+ createdAt,
99
+ event.clientId,
100
+ event.sessionId,
101
+ ]);
102
+ yield* execDb((db) => db
103
+ .prepare(sql)
104
+ .bind(...params)
105
+ .run());
106
+ }
107
+ }).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/sync-cf:durable-object:appendEvents', {
108
+ attributes: { dbName, batchLength: batch.length, engine: engine._tag },
109
+ }));
110
+ const resetStore = Effect.promise(() => ctx.storage.deleteAll()).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/sync-cf:durable-object:resetStore'));
111
+ // DO SQLite engine implementation
112
+ const getEventsDoSqlite = (cursor) => Effect.gen(function* () {
113
+ const selectCountSql = cursor === undefined
114
+ ? `SELECT COUNT(*) as total FROM "${dbName}"`
115
+ : `SELECT COUNT(*) as total FROM "${dbName}" WHERE seqNum > ?`;
116
+ let total = 0;
117
+ try {
118
+ const cursorIter = cursor === undefined ? ctx.storage.sql.exec(selectCountSql) : ctx.storage.sql.exec(selectCountSql, cursor);
119
+ for (const row of cursorIter) {
120
+ total = Number(row.total ?? 0);
121
+ }
122
+ }
123
+ catch (error) {
124
+ return yield* Effect.fail(new UnexpectedError({ cause: error, payload: { dbName, stage: 'count' } }));
125
+ }
126
+ const DO_PAGE_SIZE = 256;
127
+ const initialState = { cursor };
128
+ const fetchPage = (state) => Effect.try({
129
+ try: () => {
130
+ const sql = state.cursor === undefined
131
+ ? `SELECT * FROM "${dbName}" ORDER BY seqNum ASC LIMIT ?`
132
+ : `SELECT * FROM "${dbName}" WHERE seqNum > ? ORDER BY seqNum ASC LIMIT ?`;
133
+ const iter = state.cursor === undefined
134
+ ? ctx.storage.sql.exec(sql, DO_PAGE_SIZE)
135
+ : ctx.storage.sql.exec(sql, state.cursor, DO_PAGE_SIZE);
136
+ const rows = [];
137
+ for (const row of iter)
138
+ rows.push(row);
139
+ if (rows.length === 0) {
140
+ return Option.none();
141
+ }
142
+ const decodedRows = Chunk.fromIterable(decodeEventlogRows(rows));
143
+ const eventsChunk = Chunk.map(decodedRows, ({ createdAt, ...eventEncoded }) => ({
144
+ eventEncoded,
145
+ metadata: Option.some(SyncMetadata.make({ createdAt })),
146
+ }));
147
+ const lastSeqNum = Chunk.unsafeLast(decodedRows).seqNum;
148
+ const nextState = { cursor: lastSeqNum };
149
+ return Option.some([eventsChunk, nextState]);
150
+ },
151
+ catch: (error) => new UnexpectedError({ cause: error, payload: { dbName, stage: 'select' } }),
152
+ });
153
+ const stream = Stream.unfoldChunkEffect(initialState, fetchPage);
154
+ return { total, stream };
155
+ }).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('@livestore/sync-cf:durable-object:getEvents', {
156
+ attributes: { dbName, cursor, engine: engine._tag },
157
+ }));
158
+ const appendEventsDoSqlite = (batch, createdAt) => Effect.try({
159
+ try: () => {
160
+ if (batch.length === 0)
161
+ return;
162
+ // Keep params per statement within conservative limits (align with D1 bound params ~100)
163
+ const CHUNK_SIZE = 14;
164
+ for (let i = 0; i < batch.length; i += CHUNK_SIZE) {
165
+ const chunk = batch.slice(i, i + CHUNK_SIZE);
166
+ const placeholders = chunk.map(() => '(?, ?, ?, ?, ?, ?, ?)').join(', ');
167
+ const sql = `INSERT INTO "${dbName}" (seqNum, parentSeqNum, args, name, createdAt, clientId, sessionId) VALUES ${placeholders}`;
168
+ const params = chunk.flatMap((event) => [
169
+ event.seqNum,
170
+ event.parentSeqNum,
171
+ event.args === undefined ? null : JSON.stringify(event.args),
172
+ event.name,
173
+ createdAt,
174
+ event.clientId,
175
+ event.sessionId,
176
+ ]);
177
+ ctx.storage.sql.exec(sql, ...params);
178
+ }
179
+ },
180
+ catch: (error) => new UnexpectedError({ cause: error, payload: { dbName, stage: 'insert' } }),
181
+ }).pipe(Effect.withSpan('@livestore/sync-cf:durable-object:appendEvents', {
182
+ attributes: { dbName, batchLength: batch.length, engine: engine._tag },
183
+ }), UnexpectedError.mapToUnexpectedError);
184
+ if (engine._tag === 'd1') {
185
+ return { dbName, getEvents: getEventsD1, appendEvents: appendEventsD1, resetStore };
186
+ }
187
+ return { dbName, getEvents: getEventsDoSqlite, appendEvents: appendEventsDoSqlite, resetStore };
188
+ };
189
+ const toValidTableName = (str) => str.replaceAll(/[^a-zA-Z0-9]/g, '_');
190
+ //# sourceMappingURL=sync-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-storage.js","sourceRoot":"","sources":["../../../src/cf-worker/do/sync-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type CfTypes } from '@livestore/common-cf';
2
+ import { Effect } from '@livestore/utils/effect';
3
+ import { type DoCtxInput } from '../layer.ts';
4
+ export interface DoRpcHandlerOptions {
5
+ payload: Uint8Array<ArrayBuffer>;
6
+ input: Omit<DoCtxInput, 'from'>;
7
+ }
8
+ export declare const createDoRpcHandler: (options: DoRpcHandlerOptions) => Effect.Effect<Uint8Array<ArrayBuffer> | CfTypes.ReadableStream>;
9
+ //# sourceMappingURL=do-rpc-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/do-rpc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAA0B,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EACL,MAAM,EASP,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAIpD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,CAAA;IAChC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,eAAO,MAAM,kBAAkB,GAC7B,SAAS,mBAAmB,KAC3B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,cAAc,CAyDjB,CAAA"}
@@ -0,0 +1,45 @@
1
+ import { InvalidPullError, InvalidPushError } from '@livestore/common';
2
+ import { toDurableObjectHandler } from '@livestore/common-cf';
3
+ import { Effect, Headers, HttpServer, Layer, Logger, LogLevel, Option, RpcSerialization, Stream, } from '@livestore/utils/effect';
4
+ import { SyncDoRpc } from "../../../common/do-rpc-schema.js";
5
+ import { SyncMessage } from "../../../common/mod.js";
6
+ import { DoCtx } from "../layer.js";
7
+ import { makeEndingPullStream } from "../pull.js";
8
+ import { makePush } from "../push.js";
9
+ export const createDoRpcHandler = (options) => Effect.gen(this, function* () {
10
+ const { payload, input } = options;
11
+ // const { rpcSubscriptions, backendId, doOptions, ctx, env } = yield* DoCtx
12
+ // TODO add admin RPCs
13
+ const RpcLive = SyncDoRpc.toLayer({
14
+ 'SyncDoRpc.Ping': (_req) => {
15
+ return Effect.succeed(SyncMessage.Pong.make({}));
16
+ },
17
+ 'SyncDoRpc.Pull': (req, { headers }) => Effect.gen(this, function* () {
18
+ const { rpcSubscriptions } = yield* DoCtx;
19
+ // TODO rename `req.rpcContext` to something more appropriate
20
+ if (req.rpcContext) {
21
+ rpcSubscriptions.set(req.storeId, {
22
+ storeId: req.storeId,
23
+ payload: req.payload,
24
+ subscribedAt: Date.now(),
25
+ requestId: Headers.get(headers, 'x-rpc-request-id').pipe(Option.getOrThrow),
26
+ callerContext: req.rpcContext.callerContext,
27
+ });
28
+ }
29
+ return makeEndingPullStream(req, req.payload);
30
+ }).pipe(Stream.unwrap, Stream.map((res) => ({
31
+ ...res,
32
+ rpcRequestId: Headers.get(headers, 'x-rpc-request-id').pipe(Option.getOrThrow),
33
+ })), Stream.provideLayer(DoCtx.Default({ ...input, from: { storeId: req.storeId } })), Stream.mapError((cause) => (cause._tag === 'InvalidPullError' ? cause : InvalidPullError.make({ cause }))), Stream.tapErrorCause(Effect.log)),
34
+ 'SyncDoRpc.Push': (req) => Effect.gen(this, function* () {
35
+ const { doOptions, ctx, env, storeId } = yield* DoCtx;
36
+ const push = makePush({ storeId, payload: req.payload, options: doOptions, ctx, env });
37
+ return yield* push(req);
38
+ }).pipe(Effect.provide(DoCtx.Default({ ...input, from: { storeId: req.storeId } })), Effect.mapError((cause) => (cause._tag === 'InvalidPushError' ? cause : InvalidPushError.make({ cause }))), Effect.tapCauseLogPretty),
39
+ });
40
+ const handler = toDurableObjectHandler(SyncDoRpc, {
41
+ layer: Layer.mergeAll(RpcLive, RpcSerialization.layerJson, HttpServer.layerContext).pipe(Layer.provide(Logger.consoleWithThread('SyncDo')), Layer.provide(Logger.minimumLogLevel(LogLevel.Debug))),
42
+ });
43
+ return yield* handler(payload);
44
+ }).pipe(Effect.withSpan('createDoRpcHandler'));
45
+ //# sourceMappingURL=do-rpc-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do-rpc-server.js","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/do-rpc-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { CfTypes } from '@livestore/common-cf';
2
+ import { Effect } from '@livestore/utils/effect';
3
+ import { DoCtx } from '../layer.ts';
4
+ export declare const createHttpRpcHandler: ({ request }: {
5
+ request: CfTypes.Request;
6
+ }) => Effect.Effect<CfTypes.Response, import("effect/Cause").TimeoutException, DoCtx | import("effect/Scope").Scope>;
7
+ //# sourceMappingURL=http-rpc-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-rpc-server.d.ts","sourceRoot":"","sources":["../../../../src/cf-worker/do/transport/http-rpc-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,MAAM,EAA+C,MAAM,yBAAyB,CAAA;AAG7F,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAInC,eAAO,MAAM,oBAAoB,GAAI,aAAa;IAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAA;CAAE,mHAS5B,CAAA"}
@@ -0,0 +1,24 @@
1
+ import { Effect, HttpApp, Layer, RpcSerialization, RpcServer } from '@livestore/utils/effect';
2
+ import { SyncHttpRpc } from "../../../common/http-rpc-schema.js";
3
+ import * as SyncMessage from "../../../common/sync-message-types.js";
4
+ import { DoCtx } from "../layer.js";
5
+ import { makeEndingPullStream } from "../pull.js";
6
+ import { makePush } from "../push.js";
7
+ export const createHttpRpcHandler = ({ request }) => Effect.gen(function* () {
8
+ const handlerLayer = createHttpRpcLayer;
9
+ const httpApp = RpcServer.toHttpApp(SyncHttpRpc).pipe(Effect.provide(handlerLayer));
10
+ const webHandler = yield* httpApp.pipe(Effect.map(HttpApp.toWebHandler));
11
+ return yield* Effect.promise(() => webHandler(request)).pipe(Effect.timeout(10000));
12
+ }).pipe(Effect.withSpan('createHttpRpcHandler'));
13
+ const createHttpRpcLayer =
14
+ // TODO implement admin requests
15
+ SyncHttpRpc.toLayer({
16
+ 'SyncHttpRpc.Pull': (req) => makeEndingPullStream(req, req.payload),
17
+ 'SyncHttpRpc.Push': (req) => Effect.gen(function* () {
18
+ const { ctx, env, doOptions, storeId } = yield* DoCtx;
19
+ const push = makePush({ payload: undefined, options: doOptions, storeId, ctx, env });
20
+ return yield* push(req);
21
+ }),
22
+ 'SyncHttpRpc.Ping': () => Effect.succeed(SyncMessage.Pong.make({})),
23
+ }).pipe(Layer.provideMerge(RpcServer.layerProtocolHttp({ path: '/http-rpc' })), Layer.provideMerge(RpcSerialization.layerJson));
24
+ //# sourceMappingURL=http-rpc-server.js.map