@powersync/service-sync-rules 0.0.0-dev-20260929095716 → 0.0.0-dev-20261005120023

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 (41) hide show
  1. package/dist/HydratedSyncConfig.d.ts +2 -2
  2. package/dist/HydratedSyncConfig.js +3 -3
  3. package/dist/HydratedSyncConfig.js.map +1 -1
  4. package/dist/SourceTableConfig.d.ts +33 -0
  5. package/dist/SourceTableConfig.js +135 -0
  6. package/dist/SourceTableConfig.js.map +1 -0
  7. package/dist/StorageVersion.d.ts +0 -1
  8. package/dist/StorageVersion.js +0 -1
  9. package/dist/StorageVersion.js.map +1 -1
  10. package/dist/SyncConfig.d.ts +3 -3
  11. package/dist/SyncConfig.js +2 -2
  12. package/dist/SyncConfig.js.map +1 -1
  13. package/dist/SyncConfigParserHooks.d.ts +4 -4
  14. package/dist/TablePattern.d.ts +2 -2
  15. package/dist/TablePattern.js +17 -7
  16. package/dist/TablePattern.js.map +1 -1
  17. package/dist/from_yaml.js +22 -11
  18. package/dist/from_yaml.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/json.d.ts +1 -1
  23. package/dist/json_schema.d.ts +1 -1
  24. package/dist/json_schema.js +6 -7
  25. package/dist/json_schema.js.map +1 -1
  26. package/dist/sql_functions.d.ts +1 -1
  27. package/dist/sync_plan/evaluator/index.js +1 -1
  28. package/dist/sync_plan/evaluator/index.js.map +1 -1
  29. package/dist/sync_plan/plan.d.ts +2 -2
  30. package/dist/sync_plan/serialize.d.ts +4 -4
  31. package/dist/sync_plan/serialize.js +11 -11
  32. package/dist/sync_plan/serialize.js.map +1 -1
  33. package/dist/types.d.ts +1 -8
  34. package/dist/types.js +8 -13
  35. package/dist/types.js.map +1 -1
  36. package/package.json +5 -2
  37. package/schema/sync_config.json +253 -0
  38. package/schema/sync_rules.json +9 -38
  39. package/dist/ConnectionConfig.d.ts +0 -39
  40. package/dist/ConnectionConfig.js +0 -97
  41. package/dist/ConnectionConfig.js.map +0 -1
@@ -0,0 +1,253 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "bucket_definitions": {
5
+ "type": "object",
6
+ "description": "List of bucket definitions",
7
+ "examples": [
8
+ {
9
+ "global": {
10
+ "data": "select * from mytable"
11
+ }
12
+ }
13
+ ],
14
+ "patternProperties": {
15
+ ".*": {
16
+ "type": "object",
17
+ "required": [
18
+ "data"
19
+ ],
20
+ "examples": [
21
+ {
22
+ "data": [
23
+ "select * from mytable"
24
+ ]
25
+ }
26
+ ],
27
+ "properties": {
28
+ "accept_potentially_dangerous_queries": {
29
+ "description": "If true, disables warnings on potentially dangerous queries",
30
+ "type": "boolean"
31
+ },
32
+ "priority": {
33
+ "description": "Priority for the bucket (lower values indicate higher priority).",
34
+ "type": "integer"
35
+ },
36
+ "parameters": {
37
+ "description": "Parameter query(ies)",
38
+ "anyOf": [
39
+ {
40
+ "type": "string",
41
+ "description": "Parameter query"
42
+ },
43
+ {
44
+ "type": "array",
45
+ "description": "Parameter queries",
46
+ "items": {
47
+ "type": "string"
48
+ }
49
+ }
50
+ ]
51
+ },
52
+ "data": {
53
+ "type": "array",
54
+ "description": "Data queries",
55
+ "items": {
56
+ "type": "string"
57
+ }
58
+ }
59
+ },
60
+ "additionalProperties": false
61
+ }
62
+ }
63
+ },
64
+ "with": {
65
+ "type": "object",
66
+ "description": "Common-table expressions available to all sync streams",
67
+ "patternProperties": {
68
+ ".*": {
69
+ "type": "string"
70
+ }
71
+ }
72
+ },
73
+ "streams": {
74
+ "type": "object",
75
+ "description": "List of stream definitions",
76
+ "examples": [
77
+ {
78
+ "user_details": {
79
+ "query": "select * from users where id = auth.user_id()"
80
+ }
81
+ }
82
+ ],
83
+ "patternProperties": {
84
+ ".*": {
85
+ "type": "object",
86
+ "examples": [
87
+ {
88
+ "query": [
89
+ "select * from mytable"
90
+ ]
91
+ }
92
+ ],
93
+ "properties": {
94
+ "accept_potentially_dangerous_queries": {
95
+ "description": "If true, disables warnings on potentially dangerous queries",
96
+ "type": "boolean"
97
+ },
98
+ "auto_subscribe": {
99
+ "description": "Whether clients will subscribe to this stream by default.",
100
+ "type": "boolean"
101
+ },
102
+ "priority": {
103
+ "description": "Priority for the bucket (lower values indicate higher priority).",
104
+ "type": "integer"
105
+ },
106
+ "query": {
107
+ "description": "The SQL query defining content to sync in this stream.",
108
+ "type": "string"
109
+ },
110
+ "queries": {
111
+ "description": "SQL queries defining content to sync in this stream.",
112
+ "type": "array",
113
+ "items": {
114
+ "type": "string"
115
+ }
116
+ },
117
+ "with": {
118
+ "type": "object",
119
+ "description": "Common table expressions defining subqueries available in queries.",
120
+ "patternProperties": {
121
+ ".*": {
122
+ "type": "string"
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ },
130
+ "event_definitions": {
131
+ "type": "object",
132
+ "description": "Record of sync replication event definitions",
133
+ "examples": [
134
+ {
135
+ "write_checkpoints": {
136
+ "payloads": [
137
+ "select user_id, client_id, checkpoint from checkpoints"
138
+ ]
139
+ }
140
+ }
141
+ ],
142
+ "patternProperties": {
143
+ ".*": {
144
+ "type": [
145
+ "object"
146
+ ],
147
+ "required": [
148
+ "payloads"
149
+ ],
150
+ "examples": [
151
+ {
152
+ "payloads": [
153
+ "select user_id, client_id, checkpoint from checkpoints"
154
+ ]
155
+ }
156
+ ],
157
+ "properties": {
158
+ "payloads": {
159
+ "description": "Queries which extract event payload fields from replicated table rows.",
160
+ "type": "array",
161
+ "items": {
162
+ "type": "string"
163
+ }
164
+ },
165
+ "additionalProperties": false,
166
+ "uniqueItems": true
167
+ }
168
+ }
169
+ }
170
+ },
171
+ "config": {
172
+ "type": "object",
173
+ "description": "Compatibility, storage, and source-table settings for these definitions.",
174
+ "properties": {
175
+ "source_table_options": {
176
+ "type": "object",
177
+ "propertyNames": {
178
+ "minLength": 1,
179
+ "pattern": "^(?:[^.\"]+|\"(?:[^\"]|\"\")+\")(?:\\.(?:[^.\"]+|\"(?:[^\"]|\"\")+\")){0,2}$",
180
+ "patternErrorMessage": "Use <table>, <database>.<table>, or <connection>.<database>.<table>. Double-quote names containing dots or quotes."
181
+ },
182
+ "additionalProperties": {
183
+ "type": "object",
184
+ "properties": {},
185
+ "additionalProperties": false
186
+ }
187
+ },
188
+ "edition": {
189
+ "type": "integer",
190
+ "default": 1,
191
+ "minimum": 1,
192
+ "exclusiveMaximum": 4
193
+ },
194
+ "storage_version": {
195
+ "type": "integer",
196
+ "description": "Storage version used by the storage database.",
197
+ "enum": [
198
+ 2,
199
+ 3,
200
+ 4
201
+ ]
202
+ },
203
+ "timestamp_max_precision": {
204
+ "type": "string",
205
+ "enum": [
206
+ "seconds",
207
+ "milliseconds",
208
+ "microseconds",
209
+ "nanoseconds"
210
+ ]
211
+ },
212
+ "timestamps_iso8601": {
213
+ "type": "boolean",
214
+ "description": "Enabled by default starting from edition 2: Consistently renders timestamps with an ISO 8601-compatible format (previous versions used a space instead of a T to separate date and time)."
215
+ },
216
+ "versioned_bucket_ids": {
217
+ "type": "boolean",
218
+ "description": "Enabled by default starting from edition 2: Encode the version of sync rules in generated bucket ids, which avoids clients downloading data twice and improves client-side progress estimates."
219
+ },
220
+ "fixed_json_extract": {
221
+ "type": "boolean",
222
+ "description": "Enabled by default starting from edition 2: Old versions of the sync service used to treat `->> 'foo.bar'` as a two-element JSON path. With this compatibility option enabled, it follows modern SQLite and treats it as a single key. The `$.` prefix would be required to split on `.`."
223
+ },
224
+ "custom_postgres_types": {
225
+ "type": "boolean",
226
+ "description": "Enabled by default starting from edition 2: Map custom Postgres types into appropriate structures instead of syncing the raw string."
227
+ },
228
+ "unstable_sqlite_expression_engine": {
229
+ "type": "boolean",
230
+ "description": "Enabled by default starting from edition null: Experimental option to evaluate functions and operators in Sync Streams with SQLite instead of a JavaScript implementation."
231
+ },
232
+ "fixed_booleans_in_json": {
233
+ "type": "boolean",
234
+ "description": "Enabled by default starting from edition null: Consistently sync boolean values of a JSON object or array in source data as booleans (instead of integers 0/1)."
235
+ }
236
+ },
237
+ "additionalProperties": false
238
+ }
239
+ },
240
+ "anyOf": [
241
+ {
242
+ "required": [
243
+ "bucket_definitions"
244
+ ]
245
+ },
246
+ {
247
+ "required": [
248
+ "streams"
249
+ ]
250
+ }
251
+ ],
252
+ "additionalProperties": false
253
+ }
@@ -170,47 +170,19 @@
170
170
  },
171
171
  "config": {
172
172
  "type": "object",
173
- "description": "Compatibility, storage, and source connection settings for these definitions.",
173
+ "description": "Compatibility, storage, and source-table settings for these definitions.",
174
174
  "properties": {
175
- "connections": {
175
+ "source_table_options": {
176
176
  "type": "object",
177
177
  "propertyNames": {
178
- "minLength": 1
178
+ "minLength": 1,
179
+ "pattern": "^(?:[^.\"]+|\"(?:[^\"]|\"\")+\")(?:\\.(?:[^.\"]+|\"(?:[^\"]|\"\")+\")){0,2}$",
180
+ "patternErrorMessage": "Use <table>, <database>.<table>, or <connection>.<database>.<table>. Double-quote names containing dots or quotes."
179
181
  },
180
182
  "additionalProperties": {
181
- "anyOf": [
182
- {
183
- "type": "object",
184
- "additionalProperties": false,
185
- "maxProperties": 0
186
- },
187
- {
188
- "definitions": {},
189
- "type": "object",
190
- "properties": {
191
- "type": {
192
- "type": "string",
193
- "minLength": 1
194
- },
195
- "tables": {
196
- "type": "object",
197
- "propertyNames": {
198
- "minLength": 1
199
- },
200
- "additionalProperties": {
201
- "type": "object",
202
- "properties": {},
203
- "additionalProperties": false,
204
- "maxProperties": 0
205
- }
206
- }
207
- },
208
- "additionalProperties": false,
209
- "required": [
210
- "type"
211
- ]
212
- }
213
- ]
183
+ "type": "object",
184
+ "properties": {},
185
+ "additionalProperties": false
214
186
  }
215
187
  },
216
188
  "edition": {
@@ -221,8 +193,7 @@
221
193
  },
222
194
  "storage_version": {
223
195
  "type": "integer",
224
- "description": "Storage version used by the storage database. By default, version 2 is used.",
225
- "default": 2,
196
+ "description": "Storage version used by the storage database.",
226
197
  "enum": [
227
198
  2,
228
199
  3,
@@ -1,39 +0,0 @@
1
- import * as t from 'ts-codec';
2
- import type { JsonObject } from './json.js';
3
- /**
4
- * Options for one source table, such as `config.connections.default.tables.orders`. This repo has no table options yet.
5
- */
6
- export declare const SOURCE_TABLE_CONFIG: t.ObjectCodec<{}>;
7
- export type SourceTableConfig = t.Decoded<typeof SOURCE_TABLE_CONFIG>;
8
- /**
9
- * Shared connection structure. A source module specializes the table codec to describe its additional options.
10
- */
11
- export declare function connectionConfigCodec<T extends t.AnyCodec>(tableConfig: T): t.ObjectCodec<{
12
- type: t.IdentityCodec<t.CodecType.String>;
13
- tables: t.OptionalCodec<t.Codec<Record<string, t.Ix<T>>, Record<string, t.Ox<T>>, string, t.CodecProps>>;
14
- }>;
15
- export declare const CONNECTION_CONFIG: t.ObjectCodec<{
16
- type: t.IdentityCodec<t.CodecType.String>;
17
- tables: t.OptionalCodec<t.Codec<Record<string, {}>, Record<string, {}>, string, t.CodecProps>>;
18
- }>;
19
- export type ConnectionConfig<TTableConfig extends SourceTableConfig = SourceTableConfig> = {
20
- readonly type: string;
21
- readonly tables?: Readonly<Partial<Record<string, TTableConfig>>>;
22
- };
23
- /**
24
- * Connection tags are map keys; table names and patterns remain relative to their connection's default schema.
25
- */
26
- export type ConnectionConfigMap = Readonly<Partial<Record<string, ConnectionConfig>>>;
27
- /**
28
- * Generate the common shape while making the empty base table option explicit, regardless of generator defaults.
29
- */
30
- export declare function createConnectionConfigSchema(): JsonObject;
31
- /**
32
- * Validate and copy portable connection options, preserving module-owned fields.
33
- * Sort connection tags only: table declaration order can determine wildcard precedence, and literal object order matters.
34
- */
35
- export declare function normalizeConnectionConfig(value: unknown): ConnectionConfigMap;
36
- /**
37
- * Conservative equality: an expression rewrite may require a new snapshot even if MongoDB evaluates it identically.
38
- */
39
- export declare function connectionConfigsEqual(left: ConnectionConfigMap, right: ConnectionConfigMap): boolean;
@@ -1,97 +0,0 @@
1
- import * as t from 'ts-codec';
2
- /**
3
- * Options for one source table, such as `config.connections.default.tables.orders`. This repo has no table options yet.
4
- */
5
- export const SOURCE_TABLE_CONFIG = t.object({});
6
- /**
7
- * Shared connection structure. A source module specializes the table codec to describe its additional options.
8
- */
9
- export function connectionConfigCodec(tableConfig) {
10
- return t.object({ type: t.string, tables: t.record(tableConfig).optional() });
11
- }
12
- export const CONNECTION_CONFIG = connectionConfigCodec(SOURCE_TABLE_CONFIG);
13
- /**
14
- * Generate the common shape while making the empty base table option explicit, regardless of generator defaults.
15
- */
16
- export function createConnectionConfigSchema() {
17
- const connection = t.generateJSONSchema(CONNECTION_CONFIG, { allowAdditional: false });
18
- const properties = connection.properties;
19
- properties.type = { type: 'string', minLength: 1 };
20
- properties.tables = {
21
- type: 'object',
22
- propertyNames: { minLength: 1 },
23
- additionalProperties: {
24
- type: 'object',
25
- properties: {},
26
- additionalProperties: false,
27
- maxProperties: 0
28
- }
29
- };
30
- // The empty connection spelling means no options. Nonempty connections require their discriminator.
31
- return {
32
- type: 'object',
33
- propertyNames: { minLength: 1 },
34
- additionalProperties: {
35
- anyOf: [{ type: 'object', additionalProperties: false, maxProperties: 0 }, connection]
36
- }
37
- };
38
- }
39
- /**
40
- * Validate and copy portable connection options, preserving module-owned fields.
41
- * Sort connection tags only: table declaration order can determine wildcard precedence, and literal object order matters.
42
- */
43
- export function normalizeConnectionConfig(value) {
44
- if (value === undefined)
45
- return {};
46
- assertJsonObject(value);
47
- const entries = Object.entries(value).sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0));
48
- return Object.fromEntries(entries.flatMap(([tag, config]) => {
49
- assertJsonObject(config);
50
- if (!tag)
51
- throw new Error('A connection tag must not be empty.');
52
- if (Object.keys(config).length == 0)
53
- return [];
54
- if (typeof config.type != 'string' || !config.type)
55
- throw new Error('A connection type must not be empty.');
56
- if (config.tables !== undefined) {
57
- assertJsonObject(config.tables);
58
- for (const [table, options] of Object.entries(config.tables)) {
59
- if (!table)
60
- throw new Error('A source table name must not be empty.');
61
- assertJsonObject(options);
62
- }
63
- }
64
- return [[tag, structuredClone(config)]];
65
- }));
66
- }
67
- /**
68
- * Conservative equality: an expression rewrite may require a new snapshot even if MongoDB evaluates it identically.
69
- */
70
- export function connectionConfigsEqual(left, right) {
71
- return JSON.stringify(normalizeConnectionConfig(left)) == JSON.stringify(normalizeConnectionConfig(right));
72
- }
73
- function assertJsonObject(value) {
74
- if (value == null || typeof value != 'object' || Array.isArray(value)) {
75
- throw new Error('Connection and table configuration must be JSON objects.');
76
- }
77
- assertJsonValue(value, new Set());
78
- }
79
- function assertJsonValue(value, parents) {
80
- if (value === null || typeof value == 'string' || typeof value == 'boolean')
81
- return;
82
- if (typeof value == 'number' && Number.isFinite(value))
83
- return;
84
- if (typeof value != 'object' || parents.has(value)) {
85
- throw new Error('Connection configuration must contain finite, acyclic JSON values.');
86
- }
87
- if (!Array.isArray(value) &&
88
- Object.getPrototypeOf(value) !== Object.prototype &&
89
- Object.getPrototypeOf(value) !== null) {
90
- throw new Error('Connection configuration must contain plain JSON objects.');
91
- }
92
- parents.add(value);
93
- for (const child of Object.values(value))
94
- assertJsonValue(child, parents);
95
- parents.delete(value);
96
- }
97
- //# sourceMappingURL=ConnectionConfig.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConnectionConfig.js","sourceRoot":"","sources":["../src/ConnectionConfig.ts"],"names":[],"mappings":"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"}