@statezero/core 0.2.7 → 0.2.8
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.
- package/dist/flavours/django/manager.d.ts +7 -0
- package/dist/flavours/django/manager.js +9 -0
- package/dist/flavours/django/operationFactory.js +8 -0
- package/dist/flavours/django/queryExecutor.js +38 -3
- package/dist/flavours/django/querySet.d.ts +14 -0
- package/dist/flavours/django/querySet.js +24 -0
- package/dist/syncEngine/stores/operation.d.ts +1 -0
- package/dist/syncEngine/stores/operation.js +1 -0
- package/package.json +1 -1
|
@@ -159,6 +159,13 @@ export class Manager {
|
|
|
159
159
|
* @returns {QuerySet} A new QuerySet instance with the search applied.
|
|
160
160
|
*/
|
|
161
161
|
search(searchQuery: string, searchFields?: string[]): QuerySet<any>;
|
|
162
|
+
/**
|
|
163
|
+
* Returns a QuerySet marked as optimistic-only, meaning operations will only
|
|
164
|
+
* update local state without making backend API calls.
|
|
165
|
+
*
|
|
166
|
+
* @returns {QuerySet} A new QuerySet with optimistic-only mode enabled.
|
|
167
|
+
*/
|
|
168
|
+
get optimistic(): QuerySet<any>;
|
|
162
169
|
}
|
|
163
170
|
export type SerializerOptions = {
|
|
164
171
|
/**
|
|
@@ -202,4 +202,13 @@ export class Manager {
|
|
|
202
202
|
search(searchQuery, searchFields) {
|
|
203
203
|
return this.newQuerySet().search(searchQuery, searchFields);
|
|
204
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Returns a QuerySet marked as optimistic-only, meaning operations will only
|
|
207
|
+
* update local state without making backend API calls.
|
|
208
|
+
*
|
|
209
|
+
* @returns {QuerySet} A new QuerySet with optimistic-only mode enabled.
|
|
210
|
+
*/
|
|
211
|
+
get optimistic() {
|
|
212
|
+
return this.newQuerySet()._optimistic();
|
|
213
|
+
}
|
|
205
214
|
}
|
|
@@ -29,6 +29,7 @@ export class OperationFactory {
|
|
|
29
29
|
instances: [{ ...data, [primaryKeyField]: tempPk }],
|
|
30
30
|
queryset: queryset,
|
|
31
31
|
args: { data },
|
|
32
|
+
localOnly: queryset._optimisticOnly || false,
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
@@ -53,6 +54,7 @@ export class OperationFactory {
|
|
|
53
54
|
instances: instances,
|
|
54
55
|
queryset: queryset,
|
|
55
56
|
args: { data: dataList },
|
|
57
|
+
localOnly: queryset._optimisticOnly || false,
|
|
56
58
|
});
|
|
57
59
|
}
|
|
58
60
|
/**
|
|
@@ -96,6 +98,7 @@ export class OperationFactory {
|
|
|
96
98
|
instances: optimisticInstances,
|
|
97
99
|
queryset: queryset,
|
|
98
100
|
args: { filter, data },
|
|
101
|
+
localOnly: queryset._optimisticOnly || false,
|
|
99
102
|
});
|
|
100
103
|
}
|
|
101
104
|
/**
|
|
@@ -117,6 +120,7 @@ export class OperationFactory {
|
|
|
117
120
|
instances: instances,
|
|
118
121
|
queryset: queryset,
|
|
119
122
|
args: {},
|
|
123
|
+
localOnly: queryset._optimisticOnly || false,
|
|
120
124
|
});
|
|
121
125
|
}
|
|
122
126
|
/**
|
|
@@ -139,6 +143,7 @@ export class OperationFactory {
|
|
|
139
143
|
instances: instances,
|
|
140
144
|
queryset: queryset,
|
|
141
145
|
args: { data },
|
|
146
|
+
localOnly: queryset._optimisticOnly || false,
|
|
142
147
|
});
|
|
143
148
|
}
|
|
144
149
|
/**
|
|
@@ -156,6 +161,7 @@ export class OperationFactory {
|
|
|
156
161
|
instances: [instanceData],
|
|
157
162
|
queryset: queryset,
|
|
158
163
|
args: instanceData,
|
|
164
|
+
localOnly: queryset._optimisticOnly || false,
|
|
159
165
|
});
|
|
160
166
|
}
|
|
161
167
|
/**
|
|
@@ -195,6 +201,7 @@ export class OperationFactory {
|
|
|
195
201
|
instances: [instanceData],
|
|
196
202
|
queryset: queryset,
|
|
197
203
|
args: { lookup, defaults },
|
|
204
|
+
localOnly: queryset._optimisticOnly || false,
|
|
198
205
|
});
|
|
199
206
|
}
|
|
200
207
|
/**
|
|
@@ -235,6 +242,7 @@ export class OperationFactory {
|
|
|
235
242
|
instances: [instanceData],
|
|
236
243
|
queryset: queryset,
|
|
237
244
|
args: { lookup, defaults },
|
|
245
|
+
localOnly: queryset._optimisticOnly || false,
|
|
238
246
|
});
|
|
239
247
|
}
|
|
240
248
|
}
|
|
@@ -123,6 +123,11 @@ export class QueryExecutor {
|
|
|
123
123
|
? ModelClass.fromPk(operation.instances[0][primaryKeyField], querySet)
|
|
124
124
|
: ModelClass.fromPk(operation.instances[0][primaryKeyField], querySet);
|
|
125
125
|
let liveResult = new ResultTuple(live, isCreatingNew);
|
|
126
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
127
|
+
if (operation.localOnly) {
|
|
128
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
129
|
+
return liveResult;
|
|
130
|
+
}
|
|
126
131
|
// Make API call with original operation type for backend
|
|
127
132
|
const promise = makeApiCall(querySet, operationType, apiCallArgs, operation.operationId)
|
|
128
133
|
.then((response) => {
|
|
@@ -223,7 +228,12 @@ export class QueryExecutor {
|
|
|
223
228
|
};
|
|
224
229
|
const operation = OperationFactory.createUpdateOperation(querySet, apiCallArgs.data, querySet.build().filter);
|
|
225
230
|
const estimatedCount = operation.instances.length;
|
|
226
|
-
let liveResult = [estimatedCount, { [modelName]: estimatedCount },
|
|
231
|
+
let liveResult = [estimatedCount, { [modelName]: estimatedCount }, operation.instances];
|
|
232
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
233
|
+
if (operation.localOnly) {
|
|
234
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
235
|
+
return liveResult;
|
|
236
|
+
}
|
|
227
237
|
const promise = makeApiCall(querySet, operationType, apiCallArgs, operation.operationId)
|
|
228
238
|
.then((response) => {
|
|
229
239
|
const { data, included } = response.data || {};
|
|
@@ -258,7 +268,12 @@ export class QueryExecutor {
|
|
|
258
268
|
const operation = OperationFactory.createDeleteOperation(querySet);
|
|
259
269
|
// live placeholder: assume we delete all existing pks
|
|
260
270
|
const estimatedCount = operation.instances.length;
|
|
261
|
-
let liveResult = [estimatedCount, { [modelName]: estimatedCount },
|
|
271
|
+
let liveResult = [estimatedCount, { [modelName]: estimatedCount }, operation.instances];
|
|
272
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
273
|
+
if (operation.localOnly) {
|
|
274
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
275
|
+
return liveResult;
|
|
276
|
+
}
|
|
262
277
|
const promise = makeApiCall(querySet, operationType, {}, operation.operationId)
|
|
263
278
|
.then((response) => {
|
|
264
279
|
const deletedCount = response.metadata.deleted_count;
|
|
@@ -298,6 +313,11 @@ export class QueryExecutor {
|
|
|
298
313
|
const tempPk = operation.instances[0][ModelClass.primaryKeyField];
|
|
299
314
|
// 1) placeholder instance
|
|
300
315
|
const live = ModelClass.fromPk(tempPk, querySet);
|
|
316
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
317
|
+
if (operation.localOnly) {
|
|
318
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
319
|
+
return live;
|
|
320
|
+
}
|
|
301
321
|
// 2) kick off the async call
|
|
302
322
|
const promise = makeApiCall(querySet, operationType, apiCallArgs, operationId, async (response) => {
|
|
303
323
|
const { data } = response.data;
|
|
@@ -359,6 +379,11 @@ export class QueryExecutor {
|
|
|
359
379
|
const tempPk = instance[primaryKeyField];
|
|
360
380
|
return ModelClass.fromPk(tempPk, querySet);
|
|
361
381
|
});
|
|
382
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
383
|
+
if (operation.localOnly) {
|
|
384
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
385
|
+
return liveInstances;
|
|
386
|
+
}
|
|
362
387
|
// Kick off the async call
|
|
363
388
|
const promise = makeApiCall(querySet, operationType, apiCallArgs, operationId, async (response) => {
|
|
364
389
|
const { data } = response.data;
|
|
@@ -421,6 +446,11 @@ export class QueryExecutor {
|
|
|
421
446
|
// 1) placeholder instance
|
|
422
447
|
const initialPk = Array.isArray(querysetPks) ? querysetPks[0] : null;
|
|
423
448
|
const live = ModelClass.fromPk(initialPk, querySet);
|
|
449
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
450
|
+
if (operation.localOnly) {
|
|
451
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
452
|
+
return live;
|
|
453
|
+
}
|
|
424
454
|
// 2) async call
|
|
425
455
|
const promise = makeApiCall(querySet, operationType, { data }, operation.operationId)
|
|
426
456
|
.then((response) => {
|
|
@@ -468,7 +498,12 @@ export class QueryExecutor {
|
|
|
468
498
|
// Use factory to create operation
|
|
469
499
|
const operation = OperationFactory.createDeleteInstanceOperation(querySet, args);
|
|
470
500
|
// 1) placeholder result
|
|
471
|
-
let liveResult = [1, { [modelName]: 1 },
|
|
501
|
+
let liveResult = [1, { [modelName]: 1 }, operation.instances];
|
|
502
|
+
// If optimistic-only, skip API call and immediately confirm
|
|
503
|
+
if (operation.localOnly) {
|
|
504
|
+
operation.updateStatus(Status.CONFIRMED, operation.instances);
|
|
505
|
+
return liveResult;
|
|
506
|
+
}
|
|
472
507
|
// 2) async call
|
|
473
508
|
const promise = makeApiCall(querySet, operationType, args, operation.operationId)
|
|
474
509
|
.then((response) => {
|
|
@@ -40,6 +40,7 @@ export class QuerySet<T> {
|
|
|
40
40
|
_initialQueryset: string | undefined;
|
|
41
41
|
_serializerOptions: any;
|
|
42
42
|
_materialized: boolean;
|
|
43
|
+
_optimisticOnly: any;
|
|
43
44
|
__uuid: string;
|
|
44
45
|
__parent: any;
|
|
45
46
|
__reactivityId: any;
|
|
@@ -196,6 +197,19 @@ export class QuerySet<T> {
|
|
|
196
197
|
* @returns {QuerySet} A new QuerySet with the serializer options applied.
|
|
197
198
|
*/
|
|
198
199
|
all(serializerOptions?: SerializerOptions): QuerySet<any>;
|
|
200
|
+
/**
|
|
201
|
+
* Internal method to create an optimistic-only QuerySet.
|
|
202
|
+
* @private
|
|
203
|
+
* @returns {QuerySet} A new QuerySet with optimistic-only mode enabled.
|
|
204
|
+
*/
|
|
205
|
+
private _optimistic;
|
|
206
|
+
/**
|
|
207
|
+
* Returns a QuerySet marked as optimistic-only, meaning operations will only
|
|
208
|
+
* update local state without making backend API calls.
|
|
209
|
+
*
|
|
210
|
+
* @returns {QuerySet} A new QuerySet with optimistic-only mode enabled.
|
|
211
|
+
*/
|
|
212
|
+
get optimistic(): QuerySet<any>;
|
|
199
213
|
/**
|
|
200
214
|
* Creates a new record in the QuerySet.
|
|
201
215
|
* @param {Object} data - The fields and values for the new record.
|
|
@@ -36,6 +36,7 @@ export class QuerySet {
|
|
|
36
36
|
this._initialQueryset = config.initialQueryset;
|
|
37
37
|
this._serializerOptions = config.serializerOptions || {};
|
|
38
38
|
this._materialized = config.materialized || false;
|
|
39
|
+
this._optimisticOnly = config.optimisticOnly || false;
|
|
39
40
|
this.__uuid = v7();
|
|
40
41
|
this.__parent = parent;
|
|
41
42
|
this.__reactivityId = parent?.__reactivityId;
|
|
@@ -56,6 +57,7 @@ export class QuerySet {
|
|
|
56
57
|
initialQueryset: this._initialQueryset,
|
|
57
58
|
serializerOptions: { ...this._serializerOptions },
|
|
58
59
|
materialized: this._materialized,
|
|
60
|
+
optimisticOnly: this._optimisticOnly,
|
|
59
61
|
}, this);
|
|
60
62
|
}
|
|
61
63
|
get semanticKey() {
|
|
@@ -458,6 +460,27 @@ export class QuerySet {
|
|
|
458
460
|
}
|
|
459
461
|
return this;
|
|
460
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Internal method to create an optimistic-only QuerySet.
|
|
465
|
+
* @private
|
|
466
|
+
* @returns {QuerySet} A new QuerySet with optimistic-only mode enabled.
|
|
467
|
+
*/
|
|
468
|
+
_optimistic() {
|
|
469
|
+
this.ensureNotMaterialized();
|
|
470
|
+
return new QuerySet(this.ModelClass, {
|
|
471
|
+
...this._getConfig(),
|
|
472
|
+
optimisticOnly: true,
|
|
473
|
+
}, this);
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Returns a QuerySet marked as optimistic-only, meaning operations will only
|
|
477
|
+
* update local state without making backend API calls.
|
|
478
|
+
*
|
|
479
|
+
* @returns {QuerySet} A new QuerySet with optimistic-only mode enabled.
|
|
480
|
+
*/
|
|
481
|
+
get optimistic() {
|
|
482
|
+
return this._optimistic();
|
|
483
|
+
}
|
|
461
484
|
/**
|
|
462
485
|
* Creates a new record in the QuerySet.
|
|
463
486
|
* @param {Object} data - The fields and values for the new record.
|
|
@@ -659,6 +682,7 @@ export class QuerySet {
|
|
|
659
682
|
aggregations: this._aggregations,
|
|
660
683
|
initialQueryset: this._initialQueryset,
|
|
661
684
|
serializerOptions: this._serializerOptions,
|
|
685
|
+
optimisticOnly: this._optimisticOnly,
|
|
662
686
|
};
|
|
663
687
|
}
|
|
664
688
|
/**
|
|
@@ -60,6 +60,7 @@ export class Operation {
|
|
|
60
60
|
this.queryset = data.queryset;
|
|
61
61
|
this.args = data.args;
|
|
62
62
|
this.doNotPropagate = data.doNotPropagate || false;
|
|
63
|
+
this.localOnly = data.localOnly || false;
|
|
63
64
|
let ModelClass = this.queryset.ModelClass;
|
|
64
65
|
let instances = data.instances;
|
|
65
66
|
// guarantee instances is an array
|
package/package.json
CHANGED