nexabase-console 2.0.9 → 2.1.1
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/app/NexaApp.d.ts +3 -0
- package/dist/app/NexaApp.js +24 -1
- package/dist/firestore/FieldValue.d.ts +2 -0
- package/dist/firestore/FieldValue.js +6 -1
- package/dist/firestore/transaction.js +6 -3
- package/dist/firestore/writes.d.ts +2 -0
- package/dist/firestore/writes.js +8 -2
- package/package.json +1 -1
package/dist/app/NexaApp.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export declare class NexaApp {
|
|
|
36
36
|
get _firestoreCache(): Record<string, any>;
|
|
37
37
|
private _setupCrossTabSync;
|
|
38
38
|
_broadcastLocalMutation(path: string, action: string, data?: any): void;
|
|
39
|
+
getPendingWritesCount(): number;
|
|
39
40
|
hasPendingWrites(path: string): boolean;
|
|
40
41
|
markInflight(path: string, mutationId: string): void;
|
|
41
42
|
unmarkInflight(path: string, mutationId: string): void;
|
|
@@ -57,6 +58,8 @@ export declare class NexaApp {
|
|
|
57
58
|
action: 'set' | 'patch' | 'delete';
|
|
58
59
|
serverDocument?: any;
|
|
59
60
|
updateTime?: string;
|
|
61
|
+
mutationData?: any;
|
|
62
|
+
merge?: boolean;
|
|
60
63
|
}): Promise<{
|
|
61
64
|
data: any | null;
|
|
62
65
|
hasPendingWrites: boolean;
|
package/dist/app/NexaApp.js
CHANGED
|
@@ -66,6 +66,12 @@ class NexaApp {
|
|
|
66
66
|
_broadcastLocalMutation(path, action, data) {
|
|
67
67
|
this.syncEngine.broadcastLocalMutation(path, action, data);
|
|
68
68
|
}
|
|
69
|
+
getPendingWritesCount() {
|
|
70
|
+
if (!this.mutationQueue)
|
|
71
|
+
return 0;
|
|
72
|
+
const queue = this.mutationQueue.inMemoryQueue || [];
|
|
73
|
+
return queue.length;
|
|
74
|
+
}
|
|
69
75
|
hasPendingWrites(path) {
|
|
70
76
|
return this.mutationQueue.hasPendingWrites(path);
|
|
71
77
|
}
|
|
@@ -166,14 +172,31 @@ class NexaApp {
|
|
|
166
172
|
const db = this.indexedDB.getRawDB();
|
|
167
173
|
const queue = this.mutationQueue.inMemoryQueue;
|
|
168
174
|
const jobIndex = queue.findIndex((j) => j.id === mutationId);
|
|
169
|
-
|
|
175
|
+
let jobData = null;
|
|
176
|
+
if (jobIndex !== -1) {
|
|
177
|
+
jobData = queue[jobIndex];
|
|
170
178
|
queue.splice(jobIndex, 1);
|
|
179
|
+
}
|
|
171
180
|
if (options.action === 'delete') {
|
|
172
181
|
this.localStore.getServerBaseCache()[path] = null;
|
|
173
182
|
}
|
|
174
183
|
else if (serverDocument && serverDocument.fields) {
|
|
175
184
|
this.localStore.getServerBaseCache()[path] = (0, QueryUtils_1.reviveNexaData)(serverDocument.fields);
|
|
176
185
|
}
|
|
186
|
+
else {
|
|
187
|
+
// PROMOTION: If server returned success: true without serverDocument.fields (lightweight ACK),
|
|
188
|
+
// promote the local mutation payload to Server Base Cache so the document does not revert to null!
|
|
189
|
+
const rawData = (jobData ? jobData.data : options.mutationData) || {};
|
|
190
|
+
const isMerge = jobData ? jobData.merge : options.merge;
|
|
191
|
+
let currentBase = this.localStore.getServerBaseCache()[path];
|
|
192
|
+
currentBase = currentBase !== undefined && currentBase !== null ? (0, QueryUtils_1.cloneNexaData)(currentBase) : currentBase;
|
|
193
|
+
if (options.action === 'set' && !isMerge) {
|
|
194
|
+
this.localStore.getServerBaseCache()[path] = (0, QueryUtils_1.reviveNexaData)((0, helpers_1.applyDataTransforms)({}, rawData));
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
this.localStore.getServerBaseCache()[path] = (0, QueryUtils_1.reviveNexaData)((0, helpers_1.applyDataTransforms)(currentBase || {}, rawData));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
177
200
|
const view = this._calculateLocalView(path);
|
|
178
201
|
const rebasedData = view.data;
|
|
179
202
|
if (rebasedData === null) {
|
|
@@ -9,3 +9,5 @@ export declare const increment: (n: number) => FieldValue;
|
|
|
9
9
|
export declare const arrayUnion: (...elements: any[]) => FieldValue;
|
|
10
10
|
export declare const arrayRemove: (...elements: any[]) => FieldValue;
|
|
11
11
|
export declare const deleteField: () => FieldValue;
|
|
12
|
+
export declare const atomicIncrement: (n: number) => FieldValue;
|
|
13
|
+
export declare const atomicDecrement: (n: number) => FieldValue;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deleteField = exports.arrayRemove = exports.arrayUnion = exports.increment = exports.serverTimestamp = exports.FieldValue = void 0;
|
|
3
|
+
exports.atomicDecrement = exports.atomicIncrement = exports.deleteField = exports.arrayRemove = exports.arrayUnion = exports.increment = exports.serverTimestamp = exports.FieldValue = void 0;
|
|
4
4
|
class FieldValue {
|
|
5
5
|
constructor(method, value) {
|
|
6
6
|
this.method = method;
|
|
@@ -19,3 +19,8 @@ const arrayRemove = (...elements) => new FieldValue('arrayRemove', elements);
|
|
|
19
19
|
exports.arrayRemove = arrayRemove;
|
|
20
20
|
const deleteField = () => new FieldValue('deleteField');
|
|
21
21
|
exports.deleteField = deleteField;
|
|
22
|
+
// Helper methods for Offline-First operations (e.g. POS/Inventory systems)
|
|
23
|
+
const atomicIncrement = (n) => new FieldValue('increment', Math.abs(n));
|
|
24
|
+
exports.atomicIncrement = atomicIncrement;
|
|
25
|
+
const atomicDecrement = (n) => new FieldValue('increment', -Math.abs(n));
|
|
26
|
+
exports.atomicDecrement = atomicDecrement;
|
|
@@ -17,12 +17,15 @@ const runTransaction = async (db, updateFunction, options) => {
|
|
|
17
17
|
let res;
|
|
18
18
|
try {
|
|
19
19
|
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
|
20
|
-
throw new Error('
|
|
20
|
+
throw Object.assign(new Error('NEXA_ERR_TRANSACTION_OFFLINE'), { code: 'NEXA_ERR_TRANSACTION_OFFLINE' });
|
|
21
21
|
}
|
|
22
22
|
res = await db.client.get(`/api/firestore/${db.projectId}/documentWithMetadata?docPath=${encodeURIComponent(docRef.path)}`);
|
|
23
23
|
}
|
|
24
24
|
catch (err) {
|
|
25
|
-
|
|
25
|
+
if (err?.code === 'NEXA_ERR_TRANSACTION_OFFLINE' || err?.message === 'NEXA_ERR_TRANSACTION_OFFLINE') {
|
|
26
|
+
throw Object.assign(new Error('Transaction failed: Perangkat sedang offline atau jaringan terputus. Transaksi memerlukan koneksi aktif. Gunakan writeBatch atau runOfflineSafeTransaction untuk operasi offline.'), { code: 'NEXA_ERR_TRANSACTION_OFFLINE' });
|
|
27
|
+
}
|
|
28
|
+
throw (0, NexaError_1.toNexaError)(err);
|
|
26
29
|
}
|
|
27
30
|
const { data, updatedAt } = res.data;
|
|
28
31
|
reads.push({ path: docRef.path, readUpdatedAt: updatedAt });
|
|
@@ -48,7 +51,7 @@ const runTransaction = async (db, updateFunction, options) => {
|
|
|
48
51
|
const result = await updateFunction(transaction);
|
|
49
52
|
if (operations.length > 0 || reads.length > 0) {
|
|
50
53
|
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
|
51
|
-
throw
|
|
54
|
+
throw Object.assign(new Error('Transaction failed: Perangkat sedang offline atau jaringan terputus. Transaksi memerlukan koneksi aktif. Gunakan writeBatch atau runOfflineSafeTransaction untuk operasi offline.'), { code: 'NEXA_ERR_TRANSACTION_OFFLINE' });
|
|
52
55
|
}
|
|
53
56
|
await db.client.post(`/api/firestore/${db.projectId}/transaction`, { reads, operations, idempotencyKey }, { headers: { 'X-Idempotency-Key': idempotencyKey } });
|
|
54
57
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NexaApp } from "../app/NexaApp";
|
|
1
2
|
import { DocumentReference } from '../types/index';
|
|
2
3
|
export { FieldValue } from './FieldValue';
|
|
3
4
|
export type WriteResult<T = unknown> = {
|
|
@@ -26,3 +27,4 @@ export declare const updateDoc: (docRef: DocumentReference, data: any, options?:
|
|
|
26
27
|
export declare const deleteDoc: (docRef: DocumentReference, options?: {
|
|
27
28
|
idempotencyKey?: string;
|
|
28
29
|
}) => Promise<WriteResult>;
|
|
30
|
+
export declare const getPendingWritesCount: (db: NexaApp) => number;
|
package/dist/firestore/writes.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deleteDoc = exports.updateDoc = exports.patchDoc = exports.setDoc = exports.FieldValue = void 0;
|
|
3
|
+
exports.getPendingWritesCount = exports.deleteDoc = exports.updateDoc = exports.patchDoc = exports.setDoc = exports.FieldValue = void 0;
|
|
4
4
|
const helpers_1 = require("../utils/helpers");
|
|
5
5
|
var FieldValue_1 = require("./FieldValue");
|
|
6
6
|
Object.defineProperty(exports, "FieldValue", { enumerable: true, get: function () { return FieldValue_1.FieldValue; } });
|
|
@@ -173,7 +173,9 @@ const executeWriteMutation = async (docRef, action, data, options) => {
|
|
|
173
173
|
path: docRef.path,
|
|
174
174
|
action,
|
|
175
175
|
serverDocument: res.document,
|
|
176
|
-
updateTime: res.document?.updateTime
|
|
176
|
+
updateTime: res.document?.updateTime,
|
|
177
|
+
mutationData: data,
|
|
178
|
+
merge: options?.merge
|
|
177
179
|
});
|
|
178
180
|
}
|
|
179
181
|
catch (ackError) {
|
|
@@ -207,3 +209,7 @@ const deleteDoc = async (docRef, options) => {
|
|
|
207
209
|
return executeWriteMutation(docRef, 'delete', null, options);
|
|
208
210
|
};
|
|
209
211
|
exports.deleteDoc = deleteDoc;
|
|
212
|
+
const getPendingWritesCount = (db) => {
|
|
213
|
+
return db.getPendingWritesCount();
|
|
214
|
+
};
|
|
215
|
+
exports.getPendingWritesCount = getPendingWritesCount;
|
package/package.json
CHANGED