clefbase 1.3.7 → 1.3.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/cli.js +1 -1
- package/dist/db/batch.d.ts +62 -0
- package/dist/db/batch.d.ts.map +1 -0
- package/dist/db/batch.js +94 -0
- package/dist/db/batch.js.map +1 -0
- package/dist/db/index.d.ts +121 -2
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +198 -3
- package/dist/db/index.js.map +1 -1
- package/dist/db/transaction.d.ts +96 -0
- package/dist/db/transaction.d.ts.map +1 -0
- package/dist/db/transaction.js +130 -0
- package/dist/db/transaction.js.map +1 -0
- package/dist/field_value.d.ts +93 -0
- package/dist/field_value.d.ts.map +1 -0
- package/dist/field_value.js +161 -0
- package/dist/field_value.js.map +1 -0
- package/dist/index.d.ts +30 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { HttpClient } from "../http";
|
|
2
|
+
import type { ClefbaseDocument } from "../types";
|
|
3
|
+
type TxWriteOp = {
|
|
4
|
+
type: "set" | "update" | "delete";
|
|
5
|
+
collectionPath: string;
|
|
6
|
+
id: string;
|
|
7
|
+
data?: Record<string, unknown>;
|
|
8
|
+
merge?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Handle passed to your transaction callback.
|
|
12
|
+
* Accumulates reads and writes, then flushes them in a single atomic request.
|
|
13
|
+
*/
|
|
14
|
+
export declare class Transaction {
|
|
15
|
+
private readonly http;
|
|
16
|
+
/** @internal */
|
|
17
|
+
readonly _reads: {
|
|
18
|
+
collectionPath: string;
|
|
19
|
+
id: string;
|
|
20
|
+
}[];
|
|
21
|
+
/** @internal */
|
|
22
|
+
readonly _writes: TxWriteOp[];
|
|
23
|
+
private _writesStarted;
|
|
24
|
+
constructor(http: HttpClient);
|
|
25
|
+
/**
|
|
26
|
+
* Read a document inside the transaction.
|
|
27
|
+
* Must be called before any write operation.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const user = await tx.get(db.collection("users").doc("u1"));
|
|
31
|
+
*/
|
|
32
|
+
get<T extends ClefbaseDocument>(ref: {
|
|
33
|
+
collectionPath: string;
|
|
34
|
+
id: string;
|
|
35
|
+
}): Promise<T | null>;
|
|
36
|
+
/**
|
|
37
|
+
* Stage a full overwrite inside the transaction.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* tx.set(db.collection("users").doc("u1"), { name: "Alice", role: "admin" });
|
|
41
|
+
*/
|
|
42
|
+
set<T extends ClefbaseDocument>(ref: {
|
|
43
|
+
collectionPath: string;
|
|
44
|
+
id: string;
|
|
45
|
+
}, data: Omit<T, "_id" | "_createdAt" | "_updatedAt">): this;
|
|
46
|
+
/**
|
|
47
|
+
* Stage a merge-patch update inside the transaction.
|
|
48
|
+
* Supports FieldValue sentinels.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* tx.update(db.collection("posts").doc("p1"), { views: FieldValue.increment(1) });
|
|
52
|
+
*/
|
|
53
|
+
update<T extends ClefbaseDocument>(ref: {
|
|
54
|
+
collectionPath: string;
|
|
55
|
+
id: string;
|
|
56
|
+
}, data: Partial<Omit<T, "_id" | "_createdAt" | "_updatedAt">>): this;
|
|
57
|
+
/**
|
|
58
|
+
* Stage a document deletion inside the transaction.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* tx.delete(db.collection("sessions").doc("s9"));
|
|
62
|
+
*/
|
|
63
|
+
delete(ref: {
|
|
64
|
+
collectionPath: string;
|
|
65
|
+
id: string;
|
|
66
|
+
}): this;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Execute an atomic transaction.
|
|
70
|
+
*
|
|
71
|
+
* Your callback receives a `Transaction` handle. Call `tx.get()` to read
|
|
72
|
+
* documents, then `tx.set()` / `tx.update()` / `tx.delete()` to stage writes.
|
|
73
|
+
* The SDK sends all writes in one atomic request after your callback resolves.
|
|
74
|
+
*
|
|
75
|
+
* The callback may be retried on contention — keep it free of side effects.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* await db.runTransaction(async (tx) => {
|
|
79
|
+
* const counter = await tx.get(db.collection("stats").doc("global"));
|
|
80
|
+
* const current = (counter?.total as number) ?? 0;
|
|
81
|
+
* tx.update(db.collection("stats").doc("global"), { total: current + 1 });
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* // Transfer credits atomically
|
|
86
|
+
* await db.runTransaction(async (tx) => {
|
|
87
|
+
* const from = await tx.get(db.collection("wallets").doc(fromId));
|
|
88
|
+
* const to = await tx.get(db.collection("wallets").doc(toId));
|
|
89
|
+
* if (!from || (from.credits as number) < amount) throw new Error("Insufficient credits");
|
|
90
|
+
* tx.update(db.collection("wallets").doc(fromId), { credits: (from.credits as number) - amount });
|
|
91
|
+
* tx.update(db.collection("wallets").doc(toId), { credits: ((to?.credits as number) ?? 0) + amount });
|
|
92
|
+
* });
|
|
93
|
+
*/
|
|
94
|
+
export declare function runTransaction<T = void>(http: HttpClient, updateFn: (tx: Transaction) => Promise<T>): Promise<T>;
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/db/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAsBjD,KAAK,SAAS,GAAG;IACf,IAAI,EAAY,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,EAAE,EAAc,MAAM,CAAC;IACvB,IAAI,CAAC,EAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,KAAK,CAAC,EAAU,OAAO,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,qBAAa,WAAW;IAQV,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPjC,gBAAgB;IAChB,QAAQ,CAAC,MAAM,EAAG;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAM;IAChE,gBAAgB;IAChB,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,CAAM;IAEnC,OAAO,CAAC,cAAc,CAAS;gBAEF,IAAI,EAAE,UAAU;IAE7C;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,SAAS,gBAAgB,EAClC,GAAG,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAC1C,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAgBpB;;;;;OAKG;IACH,GAAG,CAAC,CAAC,SAAS,gBAAgB,EAC5B,GAAG,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAC3C,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,GAAG,YAAY,GAAG,YAAY,CAAC,GACjD,IAAI;IAYP;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,SAAS,gBAAgB,EAC/B,GAAG,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAC3C,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,GAC1D,IAAI;IAYP;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAS1D;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,cAAc,CAAC,CAAC,GAAG,IAAI,EAC3C,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAaZ"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Transaction = void 0;
|
|
4
|
+
exports.runTransaction = runTransaction;
|
|
5
|
+
/**
|
|
6
|
+
* Handle passed to your transaction callback.
|
|
7
|
+
* Accumulates reads and writes, then flushes them in a single atomic request.
|
|
8
|
+
*/
|
|
9
|
+
class Transaction {
|
|
10
|
+
constructor(http) {
|
|
11
|
+
this.http = http;
|
|
12
|
+
/** @internal */
|
|
13
|
+
this._reads = [];
|
|
14
|
+
/** @internal */
|
|
15
|
+
this._writes = [];
|
|
16
|
+
this._writesStarted = false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Read a document inside the transaction.
|
|
20
|
+
* Must be called before any write operation.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const user = await tx.get(db.collection("users").doc("u1"));
|
|
24
|
+
*/
|
|
25
|
+
async get(ref) {
|
|
26
|
+
if (this._writesStarted) {
|
|
27
|
+
throw new Error("Transaction: all tx.get() calls must come before any write (set/update/delete).");
|
|
28
|
+
}
|
|
29
|
+
this._reads.push({ collectionPath: ref.collectionPath, id: ref.id });
|
|
30
|
+
try {
|
|
31
|
+
return await this.http.get(`/${ref.collectionPath}/${ref.id}`);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (err.status === 404)
|
|
35
|
+
return null;
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Stage a full overwrite inside the transaction.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* tx.set(db.collection("users").doc("u1"), { name: "Alice", role: "admin" });
|
|
44
|
+
*/
|
|
45
|
+
set(ref, data) {
|
|
46
|
+
this._writesStarted = true;
|
|
47
|
+
this._writes.push({
|
|
48
|
+
type: "set",
|
|
49
|
+
collectionPath: ref.collectionPath,
|
|
50
|
+
id: ref.id,
|
|
51
|
+
data: data,
|
|
52
|
+
merge: false,
|
|
53
|
+
});
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Stage a merge-patch update inside the transaction.
|
|
58
|
+
* Supports FieldValue sentinels.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* tx.update(db.collection("posts").doc("p1"), { views: FieldValue.increment(1) });
|
|
62
|
+
*/
|
|
63
|
+
update(ref, data) {
|
|
64
|
+
this._writesStarted = true;
|
|
65
|
+
this._writes.push({
|
|
66
|
+
type: "update",
|
|
67
|
+
collectionPath: ref.collectionPath,
|
|
68
|
+
id: ref.id,
|
|
69
|
+
data: data,
|
|
70
|
+
merge: true,
|
|
71
|
+
});
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Stage a document deletion inside the transaction.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* tx.delete(db.collection("sessions").doc("s9"));
|
|
79
|
+
*/
|
|
80
|
+
delete(ref) {
|
|
81
|
+
this._writesStarted = true;
|
|
82
|
+
this._writes.push({
|
|
83
|
+
type: "delete",
|
|
84
|
+
collectionPath: ref.collectionPath,
|
|
85
|
+
id: ref.id,
|
|
86
|
+
});
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.Transaction = Transaction;
|
|
91
|
+
// ─── runTransaction ───────────────────────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Execute an atomic transaction.
|
|
94
|
+
*
|
|
95
|
+
* Your callback receives a `Transaction` handle. Call `tx.get()` to read
|
|
96
|
+
* documents, then `tx.set()` / `tx.update()` / `tx.delete()` to stage writes.
|
|
97
|
+
* The SDK sends all writes in one atomic request after your callback resolves.
|
|
98
|
+
*
|
|
99
|
+
* The callback may be retried on contention — keep it free of side effects.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* await db.runTransaction(async (tx) => {
|
|
103
|
+
* const counter = await tx.get(db.collection("stats").doc("global"));
|
|
104
|
+
* const current = (counter?.total as number) ?? 0;
|
|
105
|
+
* tx.update(db.collection("stats").doc("global"), { total: current + 1 });
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* // Transfer credits atomically
|
|
110
|
+
* await db.runTransaction(async (tx) => {
|
|
111
|
+
* const from = await tx.get(db.collection("wallets").doc(fromId));
|
|
112
|
+
* const to = await tx.get(db.collection("wallets").doc(toId));
|
|
113
|
+
* if (!from || (from.credits as number) < amount) throw new Error("Insufficient credits");
|
|
114
|
+
* tx.update(db.collection("wallets").doc(fromId), { credits: (from.credits as number) - amount });
|
|
115
|
+
* tx.update(db.collection("wallets").doc(toId), { credits: ((to?.credits as number) ?? 0) + amount });
|
|
116
|
+
* });
|
|
117
|
+
*/
|
|
118
|
+
async function runTransaction(http, updateFn) {
|
|
119
|
+
const tx = new Transaction(http);
|
|
120
|
+
const result = await updateFn(tx);
|
|
121
|
+
// Flush all writes atomically (reads already happened inline above)
|
|
122
|
+
if (tx._writes.length > 0) {
|
|
123
|
+
await http.post("/transaction", {
|
|
124
|
+
reads: tx._reads,
|
|
125
|
+
writes: tx._writes,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/db/transaction.ts"],"names":[],"mappings":";;;AA8JA,wCAgBC;AA/ID;;;GAGG;AACH,MAAa,WAAW;IAQtB,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;QAP7C,gBAAgB;QACP,WAAM,GAA8C,EAAE,CAAC;QAChE,gBAAgB;QACP,YAAO,GAAgB,EAAE,CAAC;QAE3B,mBAAc,GAAG,KAAK,CAAC;IAEiB,CAAC;IAEjD;;;;;;OAMG;IACH,KAAK,CAAC,GAAG,CACP,GAA2C;QAE3C,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAErE,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAI,IAAI,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA2B,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC7D,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CACD,GAA2C,EAC3C,IAAkD;QAElD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,IAAI,EAAY,KAAK;YACrB,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,EAAE,EAAc,GAAG,CAAC,EAAE;YACtB,IAAI,EAAY,IAA+B;YAC/C,KAAK,EAAW,KAAK;SACtB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CACJ,GAA2C,EAC3C,IAA2D;QAE3D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,IAAI,EAAY,QAAQ;YACxB,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,EAAE,EAAc,GAAG,CAAC,EAAE;YACtB,IAAI,EAAY,IAA+B;YAC/C,KAAK,EAAW,IAAI;SACrB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,GAA2C;QAChD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,IAAI,EAAY,QAAQ;YACxB,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,EAAE,EAAc,GAAG,CAAC,EAAE;SACvB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA7FD,kCA6FC;AAED,iFAAiF;AAEjF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACI,KAAK,UAAU,cAAc,CAClC,IAAgB,EAChB,QAAyC;IAEzC,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,CAAC,CAAC;IAElC,oEAAoE;IACpE,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YAC9B,KAAK,EAAG,EAAE,CAAC,MAAM;YACjB,MAAM,EAAE,EAAE,CAAC,OAAO;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export type FieldValueType = "increment" | "decrement" | "serverTimestamp" | "delete" | "arrayUnion" | "arrayRemove";
|
|
2
|
+
/**
|
|
3
|
+
* Opaque sentinel returned by every FieldValue factory.
|
|
4
|
+
* Never construct this directly — use the static helpers on FieldValue.
|
|
5
|
+
*/
|
|
6
|
+
export declare class FieldValueSentinel {
|
|
7
|
+
readonly _type: FieldValueType;
|
|
8
|
+
readonly _value?: number | unknown[] | undefined;
|
|
9
|
+
/** @internal discriminator so library code can detect sentinels */
|
|
10
|
+
readonly __fieldValue: true;
|
|
11
|
+
/** @internal */
|
|
12
|
+
constructor(_type: FieldValueType, _value?: number | unknown[] | undefined);
|
|
13
|
+
/**
|
|
14
|
+
* Serialize to the wire format the Clefbase server expects.
|
|
15
|
+
* Called automatically by JSON.stringify.
|
|
16
|
+
*/
|
|
17
|
+
toJSON(): object;
|
|
18
|
+
toString(): string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Atomic field-level sentinels for database writes.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* import { FieldValue } from "clefbase";
|
|
25
|
+
*
|
|
26
|
+
* await db.collection("posts").doc("p1").update({
|
|
27
|
+
* views: FieldValue.increment(1),
|
|
28
|
+
* score: FieldValue.decrement(0.5),
|
|
29
|
+
* publishedAt: FieldValue.serverTimestamp(),
|
|
30
|
+
* draftField: FieldValue.deleteField(),
|
|
31
|
+
* tags: FieldValue.arrayUnion("featured", "trending"),
|
|
32
|
+
* oldTags: FieldValue.arrayRemove("draft"),
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
35
|
+
export declare const FieldValue: {
|
|
36
|
+
/**
|
|
37
|
+
* Atomically increment a numeric field by `delta` (default 1).
|
|
38
|
+
* Creates the field with value `delta` if it does not yet exist.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* await ref.update({ views: FieldValue.increment(1) });
|
|
42
|
+
* await ref.update({ balance: FieldValue.increment(9.99) });
|
|
43
|
+
*/
|
|
44
|
+
readonly increment: (delta?: number) => FieldValueSentinel;
|
|
45
|
+
/**
|
|
46
|
+
* Atomically decrement a numeric field by `delta` (default 1).
|
|
47
|
+
* Sugar for increment(-delta).
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* await ref.update({ lives: FieldValue.decrement(1) });
|
|
51
|
+
*/
|
|
52
|
+
readonly decrement: (delta?: number) => FieldValueSentinel;
|
|
53
|
+
/**
|
|
54
|
+
* Set the field to the server's current timestamp (ISO 8601 string).
|
|
55
|
+
* Avoids clock-skew issues by using the server clock instead of the client.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* await ref.update({ lastSeen: FieldValue.serverTimestamp() });
|
|
59
|
+
*/
|
|
60
|
+
readonly serverTimestamp: () => FieldValueSentinel;
|
|
61
|
+
/**
|
|
62
|
+
* Remove this field from the document entirely.
|
|
63
|
+
* Only valid inside `.update()` — not `.set()`.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* await ref.update({ tempToken: FieldValue.deleteField() });
|
|
67
|
+
*/
|
|
68
|
+
readonly deleteField: () => FieldValueSentinel;
|
|
69
|
+
/**
|
|
70
|
+
* Add one or more items to an array field, ignoring duplicates.
|
|
71
|
+
* Creates the field as a new array if it does not yet exist.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* await ref.update({ roles: FieldValue.arrayUnion("editor", "moderator") });
|
|
75
|
+
*/
|
|
76
|
+
readonly arrayUnion: (...items: unknown[]) => FieldValueSentinel;
|
|
77
|
+
/**
|
|
78
|
+
* Remove one or more items from an array field (all matching occurrences).
|
|
79
|
+
* No-ops silently if the item or field does not exist.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* await ref.update({ roles: FieldValue.arrayRemove("moderator") });
|
|
83
|
+
*/
|
|
84
|
+
readonly arrayRemove: (...items: unknown[]) => FieldValueSentinel;
|
|
85
|
+
/**
|
|
86
|
+
* Type-guard — returns true if `value` is any FieldValue sentinel.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* if (FieldValue.isSentinel(val)) console.log(val._type);
|
|
90
|
+
*/
|
|
91
|
+
readonly isSentinel: (value: unknown) => value is FieldValueSentinel;
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=field_value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field_value.d.ts","sourceRoot":"","sources":["../src/field_value.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,QAAQ,GACR,YAAY,GACZ,aAAa,CAAC;AAElB;;;GAGG;AACH,qBAAa,kBAAkB;IAM3B,QAAQ,CAAC,KAAK,EAAE,cAAc;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE;IANtC,mEAAmE;IACnE,QAAQ,CAAC,YAAY,EAAG,IAAI,CAAU;IAEtC,gBAAgB;gBAEL,KAAK,EAAE,cAAc,EACrB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,YAAA;IAGtC;;;OAGG;IACH,MAAM,IAAI,MAAM;IAiBhB,QAAQ,IAAI,MAAM;CAGnB;AAID;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU;IACrB;;;;;;;OAOG;iCACc,MAAM,KAAO,kBAAkB;IAOhD;;;;;;OAMG;iCACc,MAAM,KAAO,kBAAkB;IAOhD;;;;;;OAMG;oCACgB,kBAAkB;IAIrC;;;;;;OAMG;gCACY,kBAAkB;IAIjC;;;;;;OAMG;oCACkB,OAAO,EAAE,KAAG,kBAAkB;IAOnD;;;;;;OAMG;qCACmB,OAAO,EAAE,KAAG,kBAAkB;IAOpD;;;;;OAKG;iCACe,OAAO,KAAG,KAAK,IAAI,kBAAkB;CAG/C,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── FieldValue ───────────────────────────────────────────────────────────────
|
|
3
|
+
//
|
|
4
|
+
// Firebase-style atomic field sentinels.
|
|
5
|
+
//
|
|
6
|
+
// Drop this file alongside your other SDK source files (types.ts, http.ts, …)
|
|
7
|
+
// and export FieldValue from your root index.ts.
|
|
8
|
+
//
|
|
9
|
+
// Wire format sent to the server (via toJSON / JSON.stringify):
|
|
10
|
+
//
|
|
11
|
+
// FieldValue.increment(2) → { __op: "increment", value: 2 }
|
|
12
|
+
// FieldValue.decrement(1) → { __op: "decrement", value: 1 }
|
|
13
|
+
// FieldValue.serverTimestamp() → { __op: "serverTimestamp" }
|
|
14
|
+
// FieldValue.deleteField() → { __op: "delete" }
|
|
15
|
+
// FieldValue.arrayUnion("a","b") → { __op: "arrayUnion", items: ["a","b"] }
|
|
16
|
+
// FieldValue.arrayRemove("a") → { __op: "arrayRemove", items: ["a"] }
|
|
17
|
+
//
|
|
18
|
+
// Because every sentinel implements toJSON(), your existing HttpClient's
|
|
19
|
+
// JSON.stringify(body) call serializes them automatically — no changes needed
|
|
20
|
+
// to http.ts.
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.FieldValue = exports.FieldValueSentinel = void 0;
|
|
24
|
+
/**
|
|
25
|
+
* Opaque sentinel returned by every FieldValue factory.
|
|
26
|
+
* Never construct this directly — use the static helpers on FieldValue.
|
|
27
|
+
*/
|
|
28
|
+
class FieldValueSentinel {
|
|
29
|
+
/** @internal */
|
|
30
|
+
constructor(_type, _value) {
|
|
31
|
+
this._type = _type;
|
|
32
|
+
this._value = _value;
|
|
33
|
+
/** @internal discriminator so library code can detect sentinels */
|
|
34
|
+
this.__fieldValue = true;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Serialize to the wire format the Clefbase server expects.
|
|
38
|
+
* Called automatically by JSON.stringify.
|
|
39
|
+
*/
|
|
40
|
+
toJSON() {
|
|
41
|
+
switch (this._type) {
|
|
42
|
+
case "increment":
|
|
43
|
+
return { __op: "increment", value: this._value };
|
|
44
|
+
case "decrement":
|
|
45
|
+
return { __op: "decrement", value: this._value };
|
|
46
|
+
case "serverTimestamp":
|
|
47
|
+
return { __op: "serverTimestamp" };
|
|
48
|
+
case "delete":
|
|
49
|
+
return { __op: "delete" };
|
|
50
|
+
case "arrayUnion":
|
|
51
|
+
return { __op: "arrayUnion", items: this._value };
|
|
52
|
+
case "arrayRemove":
|
|
53
|
+
return { __op: "arrayRemove", items: this._value };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
toString() {
|
|
57
|
+
return `FieldValue<${this._type}>`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.FieldValueSentinel = FieldValueSentinel;
|
|
61
|
+
// ─── Public namespace ─────────────────────────────────────────────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Atomic field-level sentinels for database writes.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* import { FieldValue } from "clefbase";
|
|
67
|
+
*
|
|
68
|
+
* await db.collection("posts").doc("p1").update({
|
|
69
|
+
* views: FieldValue.increment(1),
|
|
70
|
+
* score: FieldValue.decrement(0.5),
|
|
71
|
+
* publishedAt: FieldValue.serverTimestamp(),
|
|
72
|
+
* draftField: FieldValue.deleteField(),
|
|
73
|
+
* tags: FieldValue.arrayUnion("featured", "trending"),
|
|
74
|
+
* oldTags: FieldValue.arrayRemove("draft"),
|
|
75
|
+
* });
|
|
76
|
+
*/
|
|
77
|
+
exports.FieldValue = {
|
|
78
|
+
/**
|
|
79
|
+
* Atomically increment a numeric field by `delta` (default 1).
|
|
80
|
+
* Creates the field with value `delta` if it does not yet exist.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* await ref.update({ views: FieldValue.increment(1) });
|
|
84
|
+
* await ref.update({ balance: FieldValue.increment(9.99) });
|
|
85
|
+
*/
|
|
86
|
+
increment(delta = 1) {
|
|
87
|
+
if (typeof delta !== "number" || !isFinite(delta)) {
|
|
88
|
+
throw new TypeError("FieldValue.increment: delta must be a finite number");
|
|
89
|
+
}
|
|
90
|
+
return new FieldValueSentinel("increment", delta);
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Atomically decrement a numeric field by `delta` (default 1).
|
|
94
|
+
* Sugar for increment(-delta).
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* await ref.update({ lives: FieldValue.decrement(1) });
|
|
98
|
+
*/
|
|
99
|
+
decrement(delta = 1) {
|
|
100
|
+
if (typeof delta !== "number" || !isFinite(delta)) {
|
|
101
|
+
throw new TypeError("FieldValue.decrement: delta must be a finite number");
|
|
102
|
+
}
|
|
103
|
+
return new FieldValueSentinel("decrement", delta);
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* Set the field to the server's current timestamp (ISO 8601 string).
|
|
107
|
+
* Avoids clock-skew issues by using the server clock instead of the client.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* await ref.update({ lastSeen: FieldValue.serverTimestamp() });
|
|
111
|
+
*/
|
|
112
|
+
serverTimestamp() {
|
|
113
|
+
return new FieldValueSentinel("serverTimestamp");
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* Remove this field from the document entirely.
|
|
117
|
+
* Only valid inside `.update()` — not `.set()`.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* await ref.update({ tempToken: FieldValue.deleteField() });
|
|
121
|
+
*/
|
|
122
|
+
deleteField() {
|
|
123
|
+
return new FieldValueSentinel("delete");
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Add one or more items to an array field, ignoring duplicates.
|
|
127
|
+
* Creates the field as a new array if it does not yet exist.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* await ref.update({ roles: FieldValue.arrayUnion("editor", "moderator") });
|
|
131
|
+
*/
|
|
132
|
+
arrayUnion(...items) {
|
|
133
|
+
if (items.length === 0) {
|
|
134
|
+
throw new TypeError("FieldValue.arrayUnion: provide at least one item");
|
|
135
|
+
}
|
|
136
|
+
return new FieldValueSentinel("arrayUnion", items);
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* Remove one or more items from an array field (all matching occurrences).
|
|
140
|
+
* No-ops silently if the item or field does not exist.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* await ref.update({ roles: FieldValue.arrayRemove("moderator") });
|
|
144
|
+
*/
|
|
145
|
+
arrayRemove(...items) {
|
|
146
|
+
if (items.length === 0) {
|
|
147
|
+
throw new TypeError("FieldValue.arrayRemove: provide at least one item");
|
|
148
|
+
}
|
|
149
|
+
return new FieldValueSentinel("arrayRemove", items);
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* Type-guard — returns true if `value` is any FieldValue sentinel.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* if (FieldValue.isSentinel(val)) console.log(val._type);
|
|
156
|
+
*/
|
|
157
|
+
isSentinel(value) {
|
|
158
|
+
return value instanceof FieldValueSentinel;
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=field_value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field_value.js","sourceRoot":"","sources":["../src/field_value.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* clefbase — Firebase-style SDK for Clefbase / Cleforyx
|
|
3
3
|
*
|
|
4
4
|
* @example
|
|
5
|
-
* import { initClefbase, getDatabase, getAuth, getStorage, getHosting } from "clefbase";
|
|
5
|
+
* import { initClefbase, getDatabase, getAuth, getStorage, getHosting, FieldValue } from "clefbase";
|
|
6
6
|
*
|
|
7
7
|
* const app = initClefbase({
|
|
8
8
|
* serverUrl: "https://api.cleforyx.com",
|
|
@@ -11,13 +11,35 @@
|
|
|
11
11
|
* adminSecret: "...", // only needed for hosting
|
|
12
12
|
* });
|
|
13
13
|
*
|
|
14
|
-
* const db
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* const db = getDatabase(app);
|
|
15
|
+
*
|
|
16
|
+
* // FieldValue sentinels
|
|
17
|
+
* await db.collection("posts").doc("p1").update({
|
|
18
|
+
* views: FieldValue.increment(1),
|
|
19
|
+
* score: FieldValue.decrement(0.5),
|
|
20
|
+
* publishedAt: FieldValue.serverTimestamp(),
|
|
21
|
+
* draft: FieldValue.deleteField(),
|
|
22
|
+
* tags: FieldValue.arrayUnion("featured"),
|
|
23
|
+
* oldTags: FieldValue.arrayRemove("wip"),
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Batch writes
|
|
27
|
+
* const batch = db.batch();
|
|
28
|
+
* batch.update(db.collection("counters").doc("hits"), { n: FieldValue.increment(1) });
|
|
29
|
+
* batch.delete(db.collection("sessions").doc("expired"));
|
|
30
|
+
* await batch.commit();
|
|
31
|
+
*
|
|
32
|
+
* // Transactions
|
|
33
|
+
* await db.runTransaction(async (tx) => {
|
|
34
|
+
* const wallet = await tx.get(db.collection("wallets").doc(uid));
|
|
35
|
+
* tx.update(db.collection("wallets").doc(uid), { balance: (wallet?.balance as number ?? 0) + 10 });
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Collection-group queries
|
|
39
|
+
* const allComments = await db.collectionGroup("comments").where({ approved: true }).getDocs();
|
|
18
40
|
*/
|
|
19
41
|
export { ClefbaseApp, initClefbase, getApp, getDatabase, getAuth, getStorage, getHosting, } from "./app";
|
|
20
|
-
export { Database, CollectionReference, DocumentReference, Query } from "./db";
|
|
42
|
+
export { Database, CollectionReference, CollectionGroup, DocumentReference, Query, WriteBatch, Transaction, runTransaction, } from "./db";
|
|
21
43
|
export { Auth } from "./auth";
|
|
22
44
|
export type { GoogleButtonOptions } from "./auth";
|
|
23
45
|
export { ClefbaseStorage, StorageReference, BucketReference } from "./storage";
|
|
@@ -25,6 +47,8 @@ export type { StorageFile } from "./storage";
|
|
|
25
47
|
export type { StorageImageStatus } from "./react/StorageImage";
|
|
26
48
|
export { ClefbaseHosting, SiteReference } from "./hosting";
|
|
27
49
|
export type { HostingSite, HostingDeploy, HostingFile, DeployResult, DeployOptions, HostingStatus, DeployStatus, } from "./hosting";
|
|
50
|
+
export { FieldValue, FieldValueSentinel } from "./field_value";
|
|
51
|
+
export type { FieldValueType } from "./field_value";
|
|
28
52
|
export type { ClefbaseConfig, ClefbaseDocument, QueryOptions, QueryResult, FilterOperator, WhereClause, WhereValue, AuthUser, AuthSession, AuthResult, } from "./types";
|
|
29
53
|
export { ClefbaseError } from "./types";
|
|
30
54
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,GACX,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAQ7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
|