@powersync/service-sync-rules 0.28.0 → 0.29.0

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 (96) hide show
  1. package/LICENSE +3 -3
  2. package/dist/BaseSqlDataQuery.d.ts +9 -1
  3. package/dist/BaseSqlDataQuery.js +42 -0
  4. package/dist/BaseSqlDataQuery.js.map +1 -1
  5. package/dist/BucketDescription.d.ts +16 -0
  6. package/dist/BucketParameterQuerier.d.ts +19 -3
  7. package/dist/BucketParameterQuerier.js.map +1 -1
  8. package/dist/BucketSource.d.ts +72 -0
  9. package/dist/BucketSource.js +6 -0
  10. package/dist/BucketSource.js.map +1 -0
  11. package/dist/ExpressionType.d.ts +1 -0
  12. package/dist/ExpressionType.js.map +1 -1
  13. package/dist/SqlBucketDescriptor.d.ts +40 -8
  14. package/dist/SqlBucketDescriptor.js +78 -10
  15. package/dist/SqlBucketDescriptor.js.map +1 -1
  16. package/dist/SqlDataQuery.d.ts +4 -3
  17. package/dist/SqlDataQuery.js +10 -30
  18. package/dist/SqlDataQuery.js.map +1 -1
  19. package/dist/SqlParameterQuery.d.ts +4 -4
  20. package/dist/SqlParameterQuery.js +9 -4
  21. package/dist/SqlParameterQuery.js.map +1 -1
  22. package/dist/SqlSyncRules.d.ts +55 -7
  23. package/dist/SqlSyncRules.js +126 -47
  24. package/dist/SqlSyncRules.js.map +1 -1
  25. package/dist/StaticSqlParameterQuery.d.ts +2 -2
  26. package/dist/StaticSqlParameterQuery.js +3 -2
  27. package/dist/StaticSqlParameterQuery.js.map +1 -1
  28. package/dist/TableValuedFunctionSqlParameterQuery.d.ts +2 -2
  29. package/dist/TableValuedFunctionSqlParameterQuery.js +11 -10
  30. package/dist/TableValuedFunctionSqlParameterQuery.js.map +1 -1
  31. package/dist/TableValuedFunctions.d.ts +2 -2
  32. package/dist/TableValuedFunctions.js +38 -35
  33. package/dist/TableValuedFunctions.js.map +1 -1
  34. package/dist/compatibility.d.ts +39 -0
  35. package/dist/compatibility.js +54 -0
  36. package/dist/compatibility.js.map +1 -0
  37. package/dist/events/SqlEventDescriptor.d.ts +3 -1
  38. package/dist/events/SqlEventDescriptor.js +4 -2
  39. package/dist/events/SqlEventDescriptor.js.map +1 -1
  40. package/dist/events/SqlEventSourceQuery.d.ts +2 -1
  41. package/dist/events/SqlEventSourceQuery.js +3 -2
  42. package/dist/events/SqlEventSourceQuery.js.map +1 -1
  43. package/dist/index.d.ts +7 -0
  44. package/dist/index.js +7 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/json_schema.js +54 -1
  47. package/dist/json_schema.js.map +1 -1
  48. package/dist/request_functions.d.ts +24 -4
  49. package/dist/request_functions.js +68 -17
  50. package/dist/request_functions.js.map +1 -1
  51. package/dist/schema-generators/SchemaGenerator.js +2 -12
  52. package/dist/schema-generators/SchemaGenerator.js.map +1 -1
  53. package/dist/sql_filters.d.ts +25 -2
  54. package/dist/sql_filters.js +223 -119
  55. package/dist/sql_filters.js.map +1 -1
  56. package/dist/sql_functions.d.ts +13 -31
  57. package/dist/sql_functions.js +191 -114
  58. package/dist/sql_functions.js.map +1 -1
  59. package/dist/sql_support.d.ts +20 -0
  60. package/dist/sql_support.js +67 -14
  61. package/dist/sql_support.js.map +1 -1
  62. package/dist/streams/filter.d.ts +148 -0
  63. package/dist/streams/filter.js +426 -0
  64. package/dist/streams/filter.js.map +1 -0
  65. package/dist/streams/from_sql.d.ts +4 -0
  66. package/dist/streams/from_sql.js +375 -0
  67. package/dist/streams/from_sql.js.map +1 -0
  68. package/dist/streams/functions.d.ts +2 -0
  69. package/dist/streams/functions.js +38 -0
  70. package/dist/streams/functions.js.map +1 -0
  71. package/dist/streams/parameter.d.ts +67 -0
  72. package/dist/streams/parameter.js +2 -0
  73. package/dist/streams/parameter.js.map +1 -0
  74. package/dist/streams/stream.d.ts +40 -0
  75. package/dist/streams/stream.js +139 -0
  76. package/dist/streams/stream.js.map +1 -0
  77. package/dist/streams/utils.d.ts +1 -0
  78. package/dist/streams/utils.js +13 -0
  79. package/dist/streams/utils.js.map +1 -0
  80. package/dist/streams/variant.d.ts +122 -0
  81. package/dist/streams/variant.js +266 -0
  82. package/dist/streams/variant.js.map +1 -0
  83. package/dist/types/custom_sqlite_value.d.ts +38 -0
  84. package/dist/types/custom_sqlite_value.js +50 -0
  85. package/dist/types/custom_sqlite_value.js.map +1 -0
  86. package/dist/types/time.d.ts +33 -0
  87. package/dist/types/time.js +67 -0
  88. package/dist/types/time.js.map +1 -0
  89. package/dist/types.d.ts +52 -9
  90. package/dist/types.js +28 -2
  91. package/dist/types.js.map +1 -1
  92. package/dist/utils.d.ts +9 -6
  93. package/dist/utils.js +42 -17
  94. package/dist/utils.js.map +1 -1
  95. package/package.json +3 -3
  96. package/schema/sync_rules.json +80 -2
@@ -0,0 +1,33 @@
1
+ import { SqliteValueType } from '../ExpressionType.js';
2
+ import { CompatibilityContext } from '../compatibility.js';
3
+ import { SqliteValue } from '../types.js';
4
+ import { CustomSqliteValue } from './custom_sqlite_value.js';
5
+ /**
6
+ * In old versions of the sync service, timestamp values were formatted with a space between the date and time
7
+ * components.
8
+ *
9
+ * This is not ISO 6801 compatible, but changing it would be breaking existing users. So, this option is opt-in and
10
+ * disabled by default until a major upgrade.
11
+ */
12
+ export declare class DateTimeValue extends CustomSqliteValue {
13
+ readonly iso8601Representation: string;
14
+ private readonly fixedLegacyRepresentation;
15
+ constructor(iso8601Representation: string, fixedLegacyRepresentation?: string | undefined);
16
+ get legacyRepresentation(): string;
17
+ get sqliteType(): SqliteValueType;
18
+ toSqliteValue(context: CompatibilityContext): string;
19
+ }
20
+ /**
21
+ * In old versions of the sync service, time values didn't consistently contain a sub-second interval.
22
+ *
23
+ * A value like `12:13:14.156789` would be represented as-is, but `12:13:14.000000` would be synced as `12:13:14`. This
24
+ * is undesirable because it means that sorting values alphabetically doesn't preserve their value.
25
+ */
26
+ export declare class TimeValue extends CustomSqliteValue {
27
+ readonly timeSeconds: string;
28
+ readonly fraction: string | undefined;
29
+ constructor(timeSeconds: string, fraction?: string | undefined);
30
+ static parse(value: string): TimeValue | null;
31
+ toSqliteValue(context: CompatibilityContext): SqliteValue;
32
+ get sqliteType(): SqliteValueType;
33
+ }
@@ -0,0 +1,67 @@
1
+ import { CompatibilityOption } from '../compatibility.js';
2
+ import { CustomSqliteValue } from './custom_sqlite_value.js';
3
+ /**
4
+ * In old versions of the sync service, timestamp values were formatted with a space between the date and time
5
+ * components.
6
+ *
7
+ * This is not ISO 6801 compatible, but changing it would be breaking existing users. So, this option is opt-in and
8
+ * disabled by default until a major upgrade.
9
+ */
10
+ export class DateTimeValue extends CustomSqliteValue {
11
+ iso8601Representation;
12
+ fixedLegacyRepresentation;
13
+ // YYYY-MM-DDThh:mm:ss.sss / YYYY-MM-DDThh:mm:ss.sssZ
14
+ constructor(iso8601Representation, fixedLegacyRepresentation = undefined) {
15
+ super();
16
+ this.iso8601Representation = iso8601Representation;
17
+ this.fixedLegacyRepresentation = fixedLegacyRepresentation;
18
+ }
19
+ // YYYY-MM-DD hh:mm:ss.sss / YYYY-MM-DD hh:mm:ss.sssZ
20
+ get legacyRepresentation() {
21
+ return this.fixedLegacyRepresentation ?? this.iso8601Representation.replace('T', ' ');
22
+ }
23
+ get sqliteType() {
24
+ return 'text';
25
+ }
26
+ toSqliteValue(context) {
27
+ return context.isEnabled(CompatibilityOption.timestampsIso8601)
28
+ ? this.iso8601Representation
29
+ : this.legacyRepresentation;
30
+ }
31
+ }
32
+ /**
33
+ * In old versions of the sync service, time values didn't consistently contain a sub-second interval.
34
+ *
35
+ * A value like `12:13:14.156789` would be represented as-is, but `12:13:14.000000` would be synced as `12:13:14`. This
36
+ * is undesirable because it means that sorting values alphabetically doesn't preserve their value.
37
+ */
38
+ export class TimeValue extends CustomSqliteValue {
39
+ timeSeconds;
40
+ fraction;
41
+ constructor(timeSeconds, fraction = undefined) {
42
+ super();
43
+ this.timeSeconds = timeSeconds;
44
+ this.fraction = fraction;
45
+ }
46
+ static parse(value) {
47
+ const match = /^([\d:]+)(\.\d+)?$/.exec(value);
48
+ if (match == null) {
49
+ return null;
50
+ }
51
+ const [_, timeSeconds, fraction] = match;
52
+ return new TimeValue(timeSeconds, fraction);
53
+ }
54
+ toSqliteValue(context) {
55
+ if (context.isEnabled(CompatibilityOption.timestampsIso8601)) {
56
+ const fraction = this.fraction?.padEnd(7, '0') ?? '.000000';
57
+ return `${this.timeSeconds}${fraction}`;
58
+ }
59
+ else {
60
+ return `${this.timeSeconds}${this.fraction ?? ''}`;
61
+ }
62
+ }
63
+ get sqliteType() {
64
+ return 'text';
65
+ }
66
+ }
67
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/types/time.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAIvC;IACQ;IAJnB,qDAAqD;IAErD,YACW,qBAA6B,EACrB,4BAAgD,SAAS;QAE1E,KAAK,EAAE,CAAC;QAHC,0BAAqB,GAArB,qBAAqB,CAAQ;QACrB,8BAAyB,GAAzB,yBAAyB,CAAgC;IAG5E,CAAC;IAED,qDAAqD;IACrD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,yBAAyB,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,aAAa,CAAC,OAA6B;QACzC,OAAO,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,iBAAiB,CAAC;YAC7D,CAAC,CAAC,IAAI,CAAC,qBAAqB;YAC5B,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;IAChC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,SAAU,SAAQ,iBAAiB;IAEnC;IACA;IAFX,YACW,WAAmB,EACnB,WAA+B,SAAS;QAEjD,KAAK,EAAE,CAAC;QAHC,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAAgC;IAGnD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAa;QACxB,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,KAAY,CAAC;QAChD,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,aAAa,CAAC,OAA6B;QACzC,IAAI,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;YAC5D,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;IACH,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
package/dist/types.d.ts CHANGED
@@ -5,6 +5,8 @@ import { SyncRulesOptions } from './SqlSyncRules.js';
5
5
  import { TablePattern } from './TablePattern.js';
6
6
  import { BucketPriority } from './BucketDescription.js';
7
7
  import { ParameterLookup } from './BucketParameterQuerier.js';
8
+ import { CustomSqliteValue } from './types/custom_sqlite_value.js';
9
+ import { CompatibilityContext } from './compatibility.js';
8
10
  export interface SyncRules {
9
11
  evaluateRow(options: EvaluateRowOptions): EvaluationResult[];
10
12
  evaluateParameterRow(table: SourceTableInterface, row: SqliteRow): EvaluatedParametersResult[];
@@ -12,6 +14,10 @@ export interface SyncRules {
12
14
  export interface QueryParseOptions extends SyncRulesOptions {
13
15
  accept_potentially_dangerous_queries?: boolean;
14
16
  priority?: BucketPriority;
17
+ compatibility: CompatibilityContext;
18
+ }
19
+ export interface StreamParseOptions extends QueryParseOptions {
20
+ auto_subscribe?: boolean;
15
21
  }
16
22
  export interface EvaluatedParameters {
17
23
  lookup: ParameterLookup;
@@ -54,10 +60,17 @@ export interface ParameterValueSet {
54
60
  * JSON string of raw request parameters.
55
61
  */
56
62
  rawUserParameters: string;
63
+ userParameters: SqliteJsonRow;
64
+ /**
65
+ * For streams, the raw JSON string of stream parameters.
66
+ */
67
+ rawStreamParameters: string | null;
68
+ streamParameters: SqliteJsonRow | null;
57
69
  /**
58
70
  * JSON string of raw request parameters.
59
71
  */
60
72
  rawTokenPayload: string;
73
+ tokenParameters: SqliteJsonRow;
61
74
  userId: string;
62
75
  }
63
76
  export declare class RequestParameters implements ParameterValueSet {
@@ -67,13 +80,17 @@ export declare class RequestParameters implements ParameterValueSet {
67
80
  * JSON string of raw request parameters.
68
81
  */
69
82
  rawUserParameters: string;
83
+ streamParameters: SqliteJsonRow | null;
84
+ rawStreamParameters: string | null;
70
85
  /**
71
86
  * JSON string of raw request parameters.
72
87
  */
73
88
  rawTokenPayload: string;
74
89
  userId: string;
75
90
  constructor(tokenPayload: RequestJwtPayload, clientParameters: Record<string, any>);
91
+ constructor(params: RequestParameters);
76
92
  lookup(table: string, column: string): SqliteJsonValue;
93
+ withAddedStreamParameters(params: Record<string, any>): RequestParameters;
77
94
  }
78
95
  /**
79
96
  * A value that is both SQLite and JSON-compatible.
@@ -85,6 +102,11 @@ export type SqliteJsonValue = number | string | bigint | null;
85
102
  * A value supported by the SQLite type system.
86
103
  */
87
104
  export type SqliteValue = number | string | null | bigint | Uint8Array;
105
+ /**
106
+ * A value that is either supported by SQLite natively, or one that can be lowered into a SQLite-value given additional
107
+ * context.
108
+ */
109
+ export type SqliteInputValue = SqliteValue | CustomSqliteValue;
88
110
  /**
89
111
  * A set of values that are both SQLite and JSON-compatible.
90
112
  *
@@ -97,22 +119,21 @@ export type SqliteJsonRow = {
97
119
  * SQLite-compatible row (NULL, TEXT, INTEGER, REAL, BLOB).
98
120
  * JSON is represented as TEXT.
99
121
  */
100
- export type SqliteRow = {
101
- [column: string]: SqliteValue;
122
+ export type SqliteRow<T = SqliteValue> = {
123
+ [column: string]: T;
102
124
  };
125
+ export type SqliteInputRow = SqliteRow<SqliteInputValue>;
103
126
  /**
104
127
  * SQLite-compatible row (NULL, TEXT, INTEGER, REAL, BLOB).
105
128
  * JSON is represented as TEXT.
106
129
  *
107
130
  * Toasted values are `undefined`.
108
131
  */
109
- export type ToastableSqliteRow = {
110
- [column: string]: SqliteValue | undefined;
111
- };
132
+ export type ToastableSqliteRow<V = SqliteInputValue> = SqliteRow<V | undefined>;
112
133
  /**
113
134
  * A value as received from the database.
114
135
  */
115
- export type DatabaseInputValue = SqliteValue | boolean | DatabaseInputValue[] | JsonContainer | {
136
+ export type DatabaseInputValue = SqliteValue | boolean | DatabaseInputValue[] | JsonContainer | CustomSqliteValue | {
116
137
  [key: string]: DatabaseInputValue;
117
138
  };
118
139
  /**
@@ -166,12 +187,31 @@ export interface InputParameter {
166
187
  */
167
188
  parametersToLookupValue(parameters: ParameterValueSet): SqliteValue;
168
189
  }
169
- export interface EvaluateRowOptions {
190
+ /**
191
+ * Transforms bucket ids generated when evaluating the row by e.g. encoding version information.
192
+ *
193
+ * Because buckets are recreated on a sync rule redeploy, it makes sense to use different bucket ids (otherwise, clients
194
+ * may run into checksum errors causing a sync to take longer than necessary or breaking progress).
195
+ *
196
+ * So, this transformer receives the original bucket id as generated by defined sync rules, and can prepend a version
197
+ * identifier.
198
+ *
199
+ * Note that this transformation has not been present in older versions of the sync service. To preserve backwards
200
+ * compatibility, sync rules will not use this function without an opt-in.
201
+ */
202
+ export type BucketIdTransformer = (regularId: string) => string;
203
+ export interface EvaluateRowOptions extends TableRow {
204
+ bucketIdTransformer: BucketIdTransformer;
205
+ }
206
+ /**
207
+ * A row associated with the table it's coming from.
208
+ */
209
+ export interface TableRow<R = SqliteRow> {
170
210
  sourceTable: SourceTableInterface;
171
- record: SqliteRow;
211
+ record: R;
172
212
  }
173
213
  /**
174
- * This is a clause that matches row and parameter values.
214
+ * This is a clause that matches row and parameter values for equality.
175
215
  *
176
216
  * Example:
177
217
  * [WHERE] users.org_id = bucket.org_id
@@ -186,6 +226,9 @@ export interface ParameterMatchClause {
186
226
  * * ['token_parameters.user_id'] for a parameter query
187
227
  *
188
228
  * These parameters are always matched by this clause, and no additional parameters are matched.
229
+ *
230
+ * For a single match clause, this array will have a single element. When match clauses are combined with `AND`,
231
+ * the result is represented as a {@link ParameterMatchClause} with multiple input parameters.
189
232
  */
190
233
  inputParameters: InputParameter[];
191
234
  /**
package/dist/types.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { JSONBig } from '@powersync/service-jsonbig';
2
2
  import { toSyncRulesParameters } from './utils.js';
3
+ import { CompatibilityContext } from './compatibility.js';
3
4
  export function isEvaluationError(e) {
4
5
  return typeof e.error == 'string';
5
6
  }
@@ -16,12 +17,24 @@ export class RequestParameters {
16
17
  * JSON string of raw request parameters.
17
18
  */
18
19
  rawUserParameters;
20
+ streamParameters;
21
+ rawStreamParameters;
19
22
  /**
20
23
  * JSON string of raw request parameters.
21
24
  */
22
25
  rawTokenPayload;
23
26
  userId;
24
27
  constructor(tokenPayload, clientParameters) {
28
+ if (tokenPayload instanceof RequestParameters) {
29
+ this.tokenParameters = tokenPayload.tokenParameters;
30
+ this.userParameters = tokenPayload.userParameters;
31
+ this.rawUserParameters = tokenPayload.rawUserParameters;
32
+ this.rawTokenPayload = tokenPayload.rawTokenPayload;
33
+ this.streamParameters = tokenPayload.streamParameters;
34
+ this.rawStreamParameters = tokenPayload.rawStreamParameters;
35
+ this.userId = tokenPayload.userId;
36
+ return;
37
+ }
25
38
  // This type is verified when we verify the token
26
39
  const legacyParameters = tokenPayload.parameters;
27
40
  const tokenParameters = {
@@ -29,11 +42,15 @@ export class RequestParameters {
29
42
  // sub takes presedence over any embedded parameters
30
43
  user_id: tokenPayload.sub
31
44
  };
32
- this.tokenParameters = toSyncRulesParameters(tokenParameters);
45
+ // Client and token parameters don't contain DateTime values or other custom types, so we don't need to consider
46
+ // compatibility.
47
+ this.tokenParameters = toSyncRulesParameters(tokenParameters, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY);
33
48
  this.userId = tokenPayload.sub;
34
49
  this.rawTokenPayload = JSONBig.stringify(tokenPayload);
35
50
  this.rawUserParameters = JSONBig.stringify(clientParameters);
36
- this.userParameters = toSyncRulesParameters(clientParameters);
51
+ this.userParameters = toSyncRulesParameters(clientParameters, CompatibilityContext.FULL_BACKWARDS_COMPATIBILITY);
52
+ this.streamParameters = null;
53
+ this.rawStreamParameters = null;
37
54
  }
38
55
  lookup(table, column) {
39
56
  if (table == 'token_parameters') {
@@ -42,7 +59,16 @@ export class RequestParameters {
42
59
  else if (table == 'user_parameters') {
43
60
  return this.userParameters[column];
44
61
  }
62
+ else if (table == 'subscription_parameters' && this.streamParameters != null) {
63
+ return this.streamParameters[column];
64
+ }
45
65
  throw new Error(`Unknown table: ${table}`);
46
66
  }
67
+ withAddedStreamParameters(params) {
68
+ const clone = new RequestParameters(this);
69
+ clone.streamParameters = params;
70
+ clone.rawStreamParameters = JSONBig.stringify(params);
71
+ return clone;
72
+ }
47
73
  }
48
74
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,4BAA4B,CAAC;AAKpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+CnD,MAAM,UAAU,iBAAiB,CAAC,CAAM;IACtC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAmB;IAChD,OAAO,OAAQ,CAAkB,CAAC,MAAM,IAAI,QAAQ,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,CAA4B;IAChE,OAAO,QAAQ,IAAI,CAAC,CAAC;AACvB,CAAC;AA6BD,MAAM,OAAO,iBAAiB;IAC5B,eAAe,CAAgB;IAC/B,cAAc,CAAgB;IAE9B;;OAEG;IACH,iBAAiB,CAAS;IAE1B;;OAEG;IACH,eAAe,CAAS;IAExB,MAAM,CAAS;IAEf,YAAY,YAA+B,EAAE,gBAAqC;QAChF,iDAAiD;QACjD,MAAM,gBAAgB,GAAG,YAAY,CAAC,UAA6C,CAAC;QAEpF,MAAM,eAAe,GAAG;YACtB,GAAG,gBAAgB;YACnB,oDAAoD;YACpD,OAAO,EAAE,YAAY,CAAC,GAAG;SAC1B,CAAC;QAEF,IAAI,CAAC,eAAe,GAAG,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC;QAC/B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAEvD,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC7D,IAAI,CAAC,cAAc,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,KAAa,EAAE,MAAc;QAClC,IAAI,KAAK,IAAI,kBAAkB,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,KAAK,IAAI,iBAAiB,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/utils.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { Replacer } from '@powersync/service-jsonbig';
2
2
  import { SelectFromStatement, Statement } from 'pgsql-ast-parser';
3
- import { DatabaseInputRow, SqliteJsonRow, SqliteJsonValue, SqliteRow, SqliteValue } from './types.js';
3
+ import { DatabaseInputRow, DatabaseInputValue, SqliteInputValue, SqliteInputRow, SqliteJsonRow, SqliteJsonValue, SqliteRow, SqliteValue, BucketIdTransformer } from './types.js';
4
+ import { CompatibilityContext } from './compatibility.js';
4
5
  export declare function isSelectStatement(q: Statement): q is SelectFromStatement;
5
- export declare function getBucketId(descriptor_id: string, bucket_parameters: string[], params: Record<string, SqliteJsonValue>): string;
6
+ export declare function getBucketId(descriptor_id: string, bucket_parameters: string[], params: Record<string, SqliteJsonValue>, transformer: BucketIdTransformer): string;
6
7
  /**
7
8
  * SqliteRow -> SqliteJsonRow.
8
9
  *
@@ -16,24 +17,26 @@ export declare function filterJsonRow(data: SqliteRow): SqliteJsonRow;
16
17
  *
17
18
  * Types specifically not supported in output are `boolean` and `undefined`.
18
19
  */
19
- export declare function jsonValueToSqlite(value: null | undefined | string | number | bigint | boolean | any): SqliteValue;
20
+ export declare function jsonValueToSqlite(fixedJsonBehavior: boolean, value: null | undefined | string | number | bigint | boolean | any): SqliteValue;
20
21
  export declare function isJsonValue(value: SqliteValue): value is SqliteJsonValue;
21
22
  /**
22
23
  * Map database row to SqliteRow for use in sync rules.
23
24
  */
24
- export declare function toSyncRulesRow(row: DatabaseInputRow): SqliteRow;
25
+ export declare function toSyncRulesRow(row: DatabaseInputRow): SqliteInputRow;
25
26
  /**
26
27
  * Convert parameter query input to a SqliteJsonRow.
27
28
  *
28
29
  * @param parameters Generic JSON input
29
30
  */
30
- export declare function toSyncRulesParameters(parameters: Record<string, any>): SqliteJsonRow;
31
+ export declare function toSyncRulesParameters(parameters: Record<string, any>, context: CompatibilityContext): SqliteJsonRow;
31
32
  /**
32
33
  * Convert to a SQLITE-equivalent value: NULL, TEXT, INTEGER, REAL or BLOB.
33
34
  *
34
35
  * Any object or array is converted to JSON TEXT.
35
36
  */
36
- export declare function toSyncRulesValue(data: any, autoBigNum?: boolean, keepUndefined?: boolean): SqliteValue;
37
+ export declare function toSyncRulesValue(data: DatabaseInputValue, autoBigNum?: boolean, keepUndefined?: boolean): SqliteInputValue;
38
+ export declare function applyValueContext(value: SqliteInputValue, context: CompatibilityContext): SqliteValue;
39
+ export declare function applyRowContext<MaybeToast extends undefined = never>(value: SqliteRow<SqliteInputValue | MaybeToast>, context: CompatibilityContext): SqliteRow<SqliteValue | MaybeToast>;
37
40
  /**
38
41
  * Only use this for serializing bucket names. Bucket names should never be parsed except perhaps for debug purposes.
39
42
  *
package/dist/utils.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { JSONBig, JsonContainer, stringifyRaw } from '@powersync/service-jsonbig';
2
2
  import { SQLITE_FALSE, SQLITE_TRUE } from './sql_support.js';
3
3
  import { SyncRuleProcessingError as SyncRulesProcessingError } from './errors.js';
4
+ import { CustomArray, CustomObject, CustomSqliteValue } from './types/custom_sqlite_value.js';
4
5
  export function isSelectStatement(q) {
5
6
  return q.type == 'select';
6
7
  }
7
- export function getBucketId(descriptor_id, bucket_parameters, params) {
8
+ export function getBucketId(descriptor_id, bucket_parameters, params, transformer) {
8
9
  // Important: REAL and INTEGER values matching the same number needs the same representation in the bucket name.
9
10
  const paramArray = bucket_parameters.map((name) => params[`bucket.${name}`]);
10
- return `${descriptor_id}${JSONBucketNameSerialize.stringify(paramArray)}`;
11
+ return transformer(`${descriptor_id}${JSONBucketNameSerialize.stringify(paramArray)}`);
11
12
  }
12
13
  const DEPTH_LIMIT = 10;
13
14
  /**
@@ -32,11 +33,17 @@ export function filterJsonRow(data) {
32
33
  *
33
34
  * Types specifically not supported in output are `boolean` and `undefined`.
34
35
  */
35
- export function jsonValueToSqlite(value) {
36
+ export function jsonValueToSqlite(fixedJsonBehavior, value) {
37
+ let isObject = typeof value == 'object';
38
+ if (fixedJsonBehavior) {
39
+ // With the fixed json behavior, make json_extract() not represent a null value as 'null' but instead use a SQL NULL
40
+ // value.
41
+ isObject = isObject && value != null;
42
+ }
36
43
  if (typeof value == 'boolean') {
37
44
  return value ? SQLITE_TRUE : SQLITE_FALSE;
38
45
  }
39
- else if (typeof value == 'object' || Array.isArray(value)) {
46
+ else if (isObject || Array.isArray(value)) {
40
47
  // Objects and arrays must be stringified
41
48
  return JSONBig.stringify(value);
42
49
  }
@@ -47,7 +54,7 @@ export function jsonValueToSqlite(value) {
47
54
  export function isJsonValue(value) {
48
55
  return value == null || typeof value == 'string' || typeof value == 'number' || typeof value == 'bigint';
49
56
  }
50
- function filterJsonData(data, depth = 0) {
57
+ function filterJsonData(data, context, depth = 0) {
51
58
  if (depth > DEPTH_LIMIT) {
52
59
  // This is primarily to prevent infinite recursion
53
60
  // TODO: Proper error class
@@ -68,7 +75,7 @@ function filterJsonData(data, depth = 0) {
68
75
  return data;
69
76
  }
70
77
  else if (Array.isArray(data)) {
71
- return data.map((element) => filterJsonData(element, depth + 1));
78
+ return data.map((element) => filterJsonData(element, context, depth + 1));
72
79
  }
73
80
  else if (ArrayBuffer.isView(data)) {
74
81
  return undefined;
@@ -77,10 +84,13 @@ function filterJsonData(data, depth = 0) {
77
84
  // Can be stringified directly when using our JSONBig implementation
78
85
  return data;
79
86
  }
87
+ else if (data instanceof CustomSqliteValue) {
88
+ return data.toSqliteValue(context);
89
+ }
80
90
  else if (typeof data == 'object') {
81
91
  let record = {};
82
92
  for (let key of Object.keys(data)) {
83
- record[key] = filterJsonData(data[key], depth + 1);
93
+ record[key] = filterJsonData(data[key], context, depth + 1);
84
94
  }
85
95
  return record;
86
96
  }
@@ -103,10 +113,10 @@ export function toSyncRulesRow(row) {
103
113
  *
104
114
  * @param parameters Generic JSON input
105
115
  */
106
- export function toSyncRulesParameters(parameters) {
116
+ export function toSyncRulesParameters(parameters, context) {
107
117
  let record = {};
108
118
  for (let key of Object.keys(parameters)) {
109
- record[key] = toSyncRulesValue(parameters[key], true, false);
119
+ record[key] = applyValueContext(toSyncRulesValue(parameters[key], true, false), context);
110
120
  }
111
121
  return record;
112
122
  }
@@ -141,26 +151,41 @@ export function toSyncRulesValue(data, autoBigNum, keepUndefined) {
141
151
  return data ? SQLITE_TRUE : SQLITE_FALSE;
142
152
  }
143
153
  else if (Array.isArray(data)) {
144
- // We may be able to avoid some parse + stringify cycles here for JsonSqliteContainer.
145
- return JSONBig.stringify(data.map((element) => filterJsonData(element)));
154
+ return new CustomArray(data, filterJsonData);
146
155
  }
147
- else if (data instanceof Uint8Array) {
156
+ else if (data instanceof Uint8Array || data instanceof CustomSqliteValue) {
148
157
  return data;
149
158
  }
150
159
  else if (data instanceof JsonContainer) {
151
160
  return data.toString();
152
161
  }
153
162
  else if (typeof data == 'object') {
154
- let record = {};
155
- for (let key of Object.keys(data)) {
156
- record[key] = filterJsonData(data[key]);
157
- }
158
- return JSONBig.stringify(record);
163
+ return new CustomObject(data, filterJsonData);
159
164
  }
160
165
  else {
161
166
  return null;
162
167
  }
163
168
  }
169
+ export function applyValueContext(value, context) {
170
+ if (value instanceof CustomSqliteValue) {
171
+ return value.toSqliteValue(context);
172
+ }
173
+ else {
174
+ return value;
175
+ }
176
+ }
177
+ export function applyRowContext(value, context) {
178
+ let record = {};
179
+ for (let [key, rawValue] of Object.entries(value)) {
180
+ if (rawValue === undefined) {
181
+ record[key] = undefined;
182
+ }
183
+ else {
184
+ record[key] = applyValueContext(rawValue, context);
185
+ }
186
+ }
187
+ return record;
188
+ }
164
189
  /**
165
190
  * Only use this for serializing bucket names. Bucket names should never be parsed except perhaps for debug purposes.
166
191
  *
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@powersync/service-sync-rules",
3
3
  "repository": "https://github.com/powersync-ja/powersync-service",
4
- "version": "0.28.0",
4
+ "version": "0.29.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "license": "FSL-1.1-Apache-2.0",
7
+ "license": "FSL-1.1-ALv2",
8
8
  "publishConfig": {
9
9
  "access": "public"
10
10
  },
@@ -19,7 +19,7 @@
19
19
  "pgsql-ast-parser": "^11.1.0",
20
20
  "uuid": "^11.1.0",
21
21
  "yaml": "^2.3.1",
22
- "@powersync/service-jsonbig": "^0.17.10"
22
+ "@powersync/service-jsonbig": "^0.17.11"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^22.16.2",
@@ -61,6 +61,50 @@
61
61
  }
62
62
  }
63
63
  },
64
+ "streams": {
65
+ "type": "object",
66
+ "description": "List of stream definitions",
67
+ "examples": [
68
+ {
69
+ "user_details": {
70
+ "query": "select * from users where id = auth.user_id()"
71
+ }
72
+ }
73
+ ],
74
+ "patternProperties": {
75
+ ".*": {
76
+ "type": "object",
77
+ "required": [
78
+ "query"
79
+ ],
80
+ "examples": [
81
+ {
82
+ "query": [
83
+ "select * from mytable"
84
+ ]
85
+ }
86
+ ],
87
+ "properties": {
88
+ "accept_potentially_dangerous_queries": {
89
+ "description": "If true, disables warnings on potentially dangerous queries",
90
+ "type": "boolean"
91
+ },
92
+ "auto_subscribe": {
93
+ "description": "Whether clients will subscribe to this stream by default.",
94
+ "type": "boolean"
95
+ },
96
+ "priority": {
97
+ "description": "Priority for the bucket (lower values indicate higher priority).",
98
+ "type": "integer"
99
+ },
100
+ "query": {
101
+ "description": "The SQL query defining content to sync in this stream.",
102
+ "type": "string"
103
+ }
104
+ }
105
+ }
106
+ }
107
+ },
64
108
  "event_definitions": {
65
109
  "type": "object",
66
110
  "description": "Record of sync replication event definitions",
@@ -101,10 +145,44 @@
101
145
  }
102
146
  }
103
147
  }
148
+ },
149
+ "config": {
150
+ "type": "object",
151
+ "description": "Config declaring the compatibility level used to parse these definitions.",
152
+ "properties": {
153
+ "edition": {
154
+ "type": "integer",
155
+ "default": 1,
156
+ "minimum": 1,
157
+ "exclusiveMaximum": 3
158
+ },
159
+ "timestamps_iso8601": {
160
+ "type": "boolean",
161
+ "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)."
162
+ },
163
+ "versioned_bucket_ids": {
164
+ "type": "boolean",
165
+ "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."
166
+ },
167
+ "fixed_json_extract": {
168
+ "type": "boolean",
169
+ "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 `.`."
170
+ }
171
+ },
172
+ "additionalProperties": false
104
173
  }
105
174
  },
106
- "required": [
107
- "bucket_definitions"
175
+ "anyOf": [
176
+ {
177
+ "required": [
178
+ "bucket_definitions"
179
+ ]
180
+ },
181
+ {
182
+ "required": [
183
+ "streams"
184
+ ]
185
+ }
108
186
  ],
109
187
  "additionalProperties": false
110
188
  }