@visiolab/effect-firebase 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/README.md +81 -2
- package/dist/_virtual/_rolldown/runtime.mjs +12 -0
- package/dist/app/App.d.mts +27 -0
- package/dist/app/App.mjs +27 -0
- package/dist/app/index.d.mts +2 -0
- package/dist/app/index.mjs +1 -0
- package/dist/firestore/Collection.d.mts +423 -0
- package/dist/firestore/Collection.mjs +133 -0
- package/dist/firestore/CollectionGroup.d.mts +164 -0
- package/dist/firestore/CollectionGroup.mjs +84 -0
- package/dist/firestore/DocumentPath.d.mts +95 -0
- package/dist/firestore/DocumentPath.mjs +71 -0
- package/dist/firestore/DocumentSnapshot.d.mts +239 -0
- package/dist/firestore/DocumentSnapshot.mjs +134 -0
- package/dist/firestore/FieldValue.d.mts +332 -0
- package/dist/firestore/FieldValue.mjs +256 -0
- package/dist/firestore/Firestore.d.mts +1165 -0
- package/dist/firestore/Firestore.mjs +274 -0
- package/dist/firestore/FirestoreModel.d.mts +1232 -0
- package/dist/firestore/FirestoreModel.mjs +586 -0
- package/dist/firestore/FirestoreSchema.d.mts +567 -0
- package/dist/firestore/FirestoreSchema.mjs +419 -0
- package/dist/firestore/FirestoreValue.d.mts +145 -0
- package/dist/firestore/FirestoreValue.mjs +87 -0
- package/dist/firestore/GeoPoint.d.mts +90 -0
- package/dist/firestore/GeoPoint.mjs +75 -0
- package/dist/firestore/Patch.d.mts +73 -0
- package/dist/firestore/Patch.mjs +57 -0
- package/dist/firestore/QuerySnapshot.d.mts +107 -0
- package/dist/firestore/QuerySnapshot.mjs +43 -0
- package/dist/firestore/Timestamp.d.mts +273 -0
- package/dist/firestore/Timestamp.mjs +255 -0
- package/dist/firestore/index.d.mts +14 -0
- package/dist/firestore/index.mjs +14 -0
- package/dist/firestore/internal/collection.mjs +156 -0
- package/dist/firestore/internal/collectionGroup.mjs +64 -0
- package/dist/firestore/internal/documentPath.d.mts +4 -0
- package/dist/firestore/internal/documentPath.mjs +42 -0
- package/dist/firestore/internal/documentSnapshot.mjs +63 -0
- package/dist/firestore/internal/fieldValue.d.mts +11 -0
- package/dist/firestore/internal/fieldValue.mjs +88 -0
- package/dist/firestore/internal/firestore.mjs +145 -0
- package/dist/firestore/internal/firestoreError.d.mts +29 -0
- package/dist/firestore/internal/firestoreError.mjs +30 -0
- package/dist/firestore/internal/firestoreModel.mjs +719 -0
- package/dist/firestore/internal/firestoreSchema.mjs +123 -0
- package/dist/firestore/internal/firestoreValue.mjs +108 -0
- package/dist/firestore/internal/firestoreValueWalk.d.mts +58 -0
- package/dist/firestore/internal/firestoreValueWalk.mjs +223 -0
- package/dist/firestore/internal/geoPoint.d.mts +4 -0
- package/dist/firestore/internal/geoPoint.mjs +39 -0
- package/dist/firestore/internal/patch.mjs +19 -0
- package/dist/firestore/internal/querySnapshot.mjs +24 -0
- package/dist/firestore/internal/schemaAST.mjs +35 -0
- package/dist/firestore/internal/snapshotExtra.mjs +35 -0
- package/dist/firestore/internal/streamFromListener.mjs +12 -0
- package/dist/firestore/internal/timestamp.d.mts +4 -0
- package/dist/firestore/internal/timestamp.mjs +66 -0
- package/dist/firestore/internal/timestampSchema.mjs +31 -0
- package/dist/firestore/internal/transactionFromCallback.mjs +66 -0
- package/dist/functions/Callable.d.mts +654 -0
- package/dist/functions/Callable.mjs +450 -0
- package/dist/functions/CallableError.d.mts +297 -0
- package/dist/functions/CallableError.mjs +256 -0
- package/dist/functions/CallableMiddleware.d.mts +213 -0
- package/dist/functions/CallableMiddleware.mjs +52 -0
- package/dist/functions/CallableRequest.d.mts +166 -0
- package/dist/functions/CallableRequest.mjs +18 -0
- package/dist/functions/Caller.d.mts +103 -0
- package/dist/functions/Caller.mjs +115 -0
- package/dist/functions/DocumentTrigger.d.mts +795 -0
- package/dist/functions/DocumentTrigger.mjs +566 -0
- package/dist/functions/FirebaseFunction.d.mts +79 -0
- package/dist/functions/FirebaseFunction.mjs +4 -0
- package/dist/functions/FunctionGroup.d.mts +175 -0
- package/dist/functions/FunctionGroup.mjs +64 -0
- package/dist/functions/index.d.mts +9 -0
- package/dist/functions/index.mjs +9 -0
- package/dist/functions/internal/callable.mjs +167 -0
- package/dist/functions/internal/callableMiddleware.d.mts +19 -0
- package/dist/functions/internal/callableMiddleware.mjs +15 -0
- package/dist/functions/internal/callableRequest.mjs +6 -0
- package/dist/functions/internal/documentTrigger.d.mts +10 -0
- package/dist/functions/internal/documentTrigger.mjs +73 -0
- package/dist/functions/internal/firebaseFunction.d.mts +5 -0
- package/dist/functions/internal/firebaseFunction.mjs +24 -0
- package/dist/functions/internal/functionGroup.mjs +36 -0
- package/package.json +72 -3
- package/src/app/App.ts +24 -0
- package/src/app/index.ts +7 -0
- package/src/firestore/Collection.ts +520 -0
- package/src/firestore/CollectionGroup.ts +245 -0
- package/src/firestore/DocumentPath.ts +114 -0
- package/src/firestore/DocumentSnapshot.ts +308 -0
- package/src/firestore/FieldValue.ts +375 -0
- package/src/firestore/Firestore.ts +1432 -0
- package/src/firestore/FirestoreModel.ts +1884 -0
- package/src/firestore/FirestoreSchema.ts +643 -0
- package/src/firestore/FirestoreValue.ts +207 -0
- package/src/firestore/GeoPoint.ts +105 -0
- package/src/firestore/Patch.ts +117 -0
- package/src/firestore/QuerySnapshot.ts +150 -0
- package/src/firestore/Timestamp.ts +302 -0
- package/src/firestore/index.ts +67 -0
- package/src/firestore/internal/collection.ts +246 -0
- package/src/firestore/internal/collectionGroup.ts +81 -0
- package/src/firestore/internal/documentPath.ts +53 -0
- package/src/firestore/internal/documentSnapshot.ts +117 -0
- package/src/firestore/internal/fieldValue.ts +119 -0
- package/src/firestore/internal/firestore.ts +322 -0
- package/src/firestore/internal/firestoreError.ts +36 -0
- package/src/firestore/internal/firestoreModel.ts +1242 -0
- package/src/firestore/internal/firestoreSchema.ts +218 -0
- package/src/firestore/internal/firestoreValue.ts +202 -0
- package/src/firestore/internal/firestoreValueWalk.ts +349 -0
- package/src/firestore/internal/geoPoint.ts +59 -0
- package/src/firestore/internal/patch.ts +21 -0
- package/src/firestore/internal/querySnapshot.ts +39 -0
- package/src/firestore/internal/schemaAST.ts +83 -0
- package/src/firestore/internal/snapshotExtra.ts +47 -0
- package/src/firestore/internal/streamFromListener.ts +27 -0
- package/src/firestore/internal/timestamp.ts +119 -0
- package/src/firestore/internal/timestampSchema.ts +42 -0
- package/src/firestore/internal/transactionFromCallback.ts +106 -0
- package/src/functions/Callable.ts +855 -0
- package/src/functions/CallableError.ts +348 -0
- package/src/functions/CallableMiddleware.ts +279 -0
- package/src/functions/CallableRequest.ts +207 -0
- package/src/functions/Caller.ts +141 -0
- package/src/functions/DocumentTrigger.ts +927 -0
- package/src/functions/FirebaseFunction.ts +96 -0
- package/src/functions/FunctionGroup.ts +225 -0
- package/src/functions/index.ts +62 -0
- package/src/functions/internal/callable.ts +272 -0
- package/src/functions/internal/callableMiddleware.ts +54 -0
- package/src/functions/internal/callableRequest.ts +8 -0
- package/src/functions/internal/documentTrigger.ts +143 -0
- package/src/functions/internal/firebaseFunction.ts +58 -0
- package/src/functions/internal/functionGroup.ts +47 -0
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { isFunctionGroup } from "./internal/functionGroup.mjs";
|
|
3
|
+
import { changeEvent, createdEvent as createdEvent$1, deletedEvent as deletedEvent$1, deployment as deployment$1, kind, make, serve as serve$1, toLayer as toLayer$1 } from "./internal/documentTrigger.mjs";
|
|
4
|
+
// src/functions/DocumentTrigger.ts
|
|
5
|
+
var DocumentTrigger_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
created: () => created,
|
|
7
|
+
createdEvent: () => createdEvent,
|
|
8
|
+
deleted: () => deleted,
|
|
9
|
+
deletedEvent: () => deletedEvent,
|
|
10
|
+
deployment: () => deployment,
|
|
11
|
+
serve: () => serve,
|
|
12
|
+
toLayer: () => toLayer,
|
|
13
|
+
updated: () => updated,
|
|
14
|
+
updatedEvent: () => updatedEvent,
|
|
15
|
+
written: () => written,
|
|
16
|
+
writtenEvent: () => writtenEvent
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* The group and the trigger that the arguments of an overload taking
|
|
20
|
+
* `(trigger, ...)` or `(group, name, ...)` name.
|
|
21
|
+
*/
|
|
22
|
+
const target = (args) => isFunctionGroup(args[0]) ? [args[0], args[0].functions[args[1]]] : [void 0, args[0]];
|
|
23
|
+
/**
|
|
24
|
+
* Declares a trigger that runs when a document of `collection` is created.
|
|
25
|
+
*
|
|
26
|
+
* **When to use**
|
|
27
|
+
*
|
|
28
|
+
* Use to react to new documents of a collection on the server. Use a
|
|
29
|
+
* `Callable` instead when the client asks for the work by name.
|
|
30
|
+
*
|
|
31
|
+
* **Details**
|
|
32
|
+
*
|
|
33
|
+
* Its handler gets a {@link Created} event. It takes one collection,
|
|
34
|
+
* whatever its depth: the path pattern it is deployed with is derived from
|
|
35
|
+
* the collection's path, with a wildcard for each parent document's id and
|
|
36
|
+
* for the document's id. A collection group can't be watched; declare a
|
|
37
|
+
* trigger for each of its collections.
|
|
38
|
+
*
|
|
39
|
+
* Firebase delivers each event at least once. Make the handler idempotent,
|
|
40
|
+
* keyed on the event's `id`.
|
|
41
|
+
*
|
|
42
|
+
* @example Declaring a trigger on a subcollection
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { Schema } from "effect";
|
|
45
|
+
* import { Collection, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
46
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
47
|
+
*
|
|
48
|
+
* class User extends FirestoreModel.Class<User>("User")({ name: Schema.String }) {}
|
|
49
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
50
|
+
*
|
|
51
|
+
* const Posts = Collection.make("users", User).subcollection("posts", Post);
|
|
52
|
+
*
|
|
53
|
+
* // Runs for each post created under any user.
|
|
54
|
+
* const OnPostCreated = DocumentTrigger.created("onPostCreated", Posts);
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @see {@link updated} for running when an existing document changes
|
|
58
|
+
* @see {@link deleted} for running when a document is deleted
|
|
59
|
+
* @see {@link written} for running on a create, an update and a delete alike
|
|
60
|
+
* @see {@link toLayer} for implementing the trigger
|
|
61
|
+
* @see {@link createdEvent} for building its event in a test
|
|
62
|
+
* @see {@link FunctionGroup.make} for collecting Functions under one prefix
|
|
63
|
+
* @see {@link Callable.make} for declaring a Function the client calls
|
|
64
|
+
*
|
|
65
|
+
* @stability unstable
|
|
66
|
+
* @category constructors
|
|
67
|
+
* @since 0.3.0
|
|
68
|
+
*/
|
|
69
|
+
const created = (name, collection) => make({
|
|
70
|
+
kind,
|
|
71
|
+
name,
|
|
72
|
+
event: "created",
|
|
73
|
+
collection
|
|
74
|
+
});
|
|
75
|
+
/**
|
|
76
|
+
* Builds the event of a {@link created} trigger from the created document's
|
|
77
|
+
* snapshot.
|
|
78
|
+
*
|
|
79
|
+
* **When to use**
|
|
80
|
+
*
|
|
81
|
+
* Use in a test, to run a handler through {@link serve} with an event of
|
|
82
|
+
* your own. The functions package builds its events with it too.
|
|
83
|
+
*
|
|
84
|
+
* **Details**
|
|
85
|
+
*
|
|
86
|
+
* The event's `ref` is the snapshot's. Build the snapshot with
|
|
87
|
+
* `DocumentSnapshot.existing` and the stored data as Firestore Values.
|
|
88
|
+
*
|
|
89
|
+
* @example Building an event for a test
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { Schema } from "effect";
|
|
92
|
+
* import { Collection, DocumentSnapshot, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
93
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
94
|
+
*
|
|
95
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
96
|
+
*
|
|
97
|
+
* const Posts = Collection.make("posts", Post);
|
|
98
|
+
*
|
|
99
|
+
* const event = DocumentTrigger.createdEvent({
|
|
100
|
+
* id: "event-1",
|
|
101
|
+
* time: "2026-01-01T00:00:00.000Z",
|
|
102
|
+
* snapshot: DocumentSnapshot.existing(Posts.doc(Posts.id.make("hello")), { title: "Hello" }),
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @see {@link created} for declaring the trigger
|
|
107
|
+
* @see {@link serve} for running the event through the handler
|
|
108
|
+
* @see {@link Created} for the event it builds
|
|
109
|
+
*
|
|
110
|
+
* @stability unstable
|
|
111
|
+
* @category constructors
|
|
112
|
+
* @since 0.3.0
|
|
113
|
+
*/
|
|
114
|
+
const createdEvent = createdEvent$1;
|
|
115
|
+
/**
|
|
116
|
+
* Declares a trigger that runs when a document of `collection` is deleted.
|
|
117
|
+
*
|
|
118
|
+
* **When to use**
|
|
119
|
+
*
|
|
120
|
+
* Use to clean up after a document of a collection is deleted, such as
|
|
121
|
+
* removing what refers to it.
|
|
122
|
+
*
|
|
123
|
+
* **Details**
|
|
124
|
+
*
|
|
125
|
+
* Its handler gets a {@link Deleted} event, with the document as it was just
|
|
126
|
+
* before it was deleted. It is deployed at the same path pattern as a
|
|
127
|
+
* {@link created} trigger on the same collection.
|
|
128
|
+
*
|
|
129
|
+
* Firebase delivers each event at least once. Make the handler idempotent,
|
|
130
|
+
* keyed on the event's `id`.
|
|
131
|
+
*
|
|
132
|
+
* @example Reading the deleted document
|
|
133
|
+
* ```ts
|
|
134
|
+
* import { Effect, Schema } from "effect";
|
|
135
|
+
* import { Collection, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
136
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
137
|
+
*
|
|
138
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
139
|
+
*
|
|
140
|
+
* const OnPostDeleted = DocumentTrigger.deleted("onPostDeleted", Collection.make("posts", Post));
|
|
141
|
+
*
|
|
142
|
+
* const OnPostDeletedLive = DocumentTrigger.toLayer(OnPostDeleted, (event) =>
|
|
143
|
+
* Effect.flatMap(event.snapshot.data, (post) => Effect.log(`Deleted ${post.title}`)),
|
|
144
|
+
* );
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* @see {@link created} for running when a document is created
|
|
148
|
+
* @see {@link updated} for running when an existing document changes
|
|
149
|
+
* @see {@link written} for running on a create, an update and a delete alike
|
|
150
|
+
* @see {@link toLayer} for implementing the trigger
|
|
151
|
+
* @see {@link deletedEvent} for building its event in a test
|
|
152
|
+
* @see {@link FunctionGroup.make} for collecting Functions under one prefix
|
|
153
|
+
*
|
|
154
|
+
* @stability unstable
|
|
155
|
+
* @category constructors
|
|
156
|
+
* @since 0.3.0
|
|
157
|
+
*/
|
|
158
|
+
const deleted = (name, collection) => make({
|
|
159
|
+
kind,
|
|
160
|
+
name,
|
|
161
|
+
event: "deleted",
|
|
162
|
+
collection
|
|
163
|
+
});
|
|
164
|
+
/**
|
|
165
|
+
* Builds the event of a {@link deleted} trigger from the snapshot of the
|
|
166
|
+
* document as it was just before it was deleted.
|
|
167
|
+
*
|
|
168
|
+
* **When to use**
|
|
169
|
+
*
|
|
170
|
+
* Use in a test, to run a handler through {@link serve} with an event of
|
|
171
|
+
* your own. The functions package builds its events with it too.
|
|
172
|
+
*
|
|
173
|
+
* **Details**
|
|
174
|
+
*
|
|
175
|
+
* The event's `ref` is the snapshot's. Build the snapshot with
|
|
176
|
+
* `DocumentSnapshot.existing` and the document's last data as Firestore
|
|
177
|
+
* Values.
|
|
178
|
+
*
|
|
179
|
+
* @example Building an event for a test
|
|
180
|
+
* ```ts
|
|
181
|
+
* import { Schema } from "effect";
|
|
182
|
+
* import { Collection, DocumentSnapshot, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
183
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
184
|
+
*
|
|
185
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
186
|
+
*
|
|
187
|
+
* const Posts = Collection.make("posts", Post);
|
|
188
|
+
*
|
|
189
|
+
* const event = DocumentTrigger.deletedEvent({
|
|
190
|
+
* id: "event-1",
|
|
191
|
+
* time: "2026-01-01T00:00:00.000Z",
|
|
192
|
+
* snapshot: DocumentSnapshot.existing(Posts.doc(Posts.id.make("hello")), { title: "Hello" }),
|
|
193
|
+
* });
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* @see {@link deleted} for declaring the trigger
|
|
197
|
+
* @see {@link serve} for running the event through the handler
|
|
198
|
+
* @see {@link Deleted} for the event it builds
|
|
199
|
+
*
|
|
200
|
+
* @stability unstable
|
|
201
|
+
* @category constructors
|
|
202
|
+
* @since 0.3.0
|
|
203
|
+
*/
|
|
204
|
+
const deletedEvent = deletedEvent$1;
|
|
205
|
+
/**
|
|
206
|
+
* Declares a trigger that runs when a document of `collection` that already
|
|
207
|
+
* exists is changed.
|
|
208
|
+
*
|
|
209
|
+
* **When to use**
|
|
210
|
+
*
|
|
211
|
+
* Use to react to changes to existing documents, with the data before and
|
|
212
|
+
* after the change at hand.
|
|
213
|
+
*
|
|
214
|
+
* **Details**
|
|
215
|
+
*
|
|
216
|
+
* Its handler gets an {@link Updated} event, with the document before and
|
|
217
|
+
* after the update. Creating or deleting a document doesn't run it.
|
|
218
|
+
*
|
|
219
|
+
* Firebase delivers each event at least once. Make the handler idempotent,
|
|
220
|
+
* keyed on the event's `id`.
|
|
221
|
+
*
|
|
222
|
+
* @example Reacting to a changed title
|
|
223
|
+
* ```ts
|
|
224
|
+
* import { Effect, Schema } from "effect";
|
|
225
|
+
* import { Collection, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
226
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
227
|
+
*
|
|
228
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
229
|
+
*
|
|
230
|
+
* const OnPostUpdated = DocumentTrigger.updated("onPostUpdated", Collection.make("posts", Post));
|
|
231
|
+
*
|
|
232
|
+
* const OnPostUpdatedLive = DocumentTrigger.toLayer(OnPostUpdated, (event) =>
|
|
233
|
+
* Effect.gen(function* () {
|
|
234
|
+
* const before = yield* event.before.data;
|
|
235
|
+
* const after = yield* event.after.data;
|
|
236
|
+
* if (before.title !== after.title) {
|
|
237
|
+
* yield* Effect.log(`Renamed ${before.title} to ${after.title}`);
|
|
238
|
+
* }
|
|
239
|
+
* }),
|
|
240
|
+
* );
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* @see {@link created} for running when a document is created
|
|
244
|
+
* @see {@link deleted} for running when a document is deleted
|
|
245
|
+
* @see {@link written} for running on a create and a delete too
|
|
246
|
+
* @see {@link toLayer} for implementing the trigger
|
|
247
|
+
* @see {@link updatedEvent} for building its event in a test
|
|
248
|
+
* @see {@link FunctionGroup.make} for collecting Functions under one prefix
|
|
249
|
+
*
|
|
250
|
+
* @stability unstable
|
|
251
|
+
* @category constructors
|
|
252
|
+
* @since 0.3.0
|
|
253
|
+
*/
|
|
254
|
+
const updated = (name, collection) => make({
|
|
255
|
+
kind,
|
|
256
|
+
name,
|
|
257
|
+
event: "updated",
|
|
258
|
+
collection
|
|
259
|
+
});
|
|
260
|
+
/**
|
|
261
|
+
* Builds the event of an {@link updated} trigger from the snapshots of the
|
|
262
|
+
* document before and after the update.
|
|
263
|
+
*
|
|
264
|
+
* **When to use**
|
|
265
|
+
*
|
|
266
|
+
* Use in a test, to run a handler through {@link serve} with an event of
|
|
267
|
+
* your own. The functions package builds its events with it too.
|
|
268
|
+
*
|
|
269
|
+
* **Details**
|
|
270
|
+
*
|
|
271
|
+
* Both snapshots are of the same document. The event's `ref` is the one of
|
|
272
|
+
* `after`. Build each with `DocumentSnapshot.existing`.
|
|
273
|
+
*
|
|
274
|
+
* @example Building an event for a test
|
|
275
|
+
* ```ts
|
|
276
|
+
* import { Schema } from "effect";
|
|
277
|
+
* import { Collection, DocumentSnapshot, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
278
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
279
|
+
*
|
|
280
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
281
|
+
*
|
|
282
|
+
* const Posts = Collection.make("posts", Post);
|
|
283
|
+
* const ref = Posts.doc(Posts.id.make("hello"));
|
|
284
|
+
*
|
|
285
|
+
* const event = DocumentTrigger.updatedEvent({
|
|
286
|
+
* id: "event-1",
|
|
287
|
+
* time: "2026-01-01T00:00:00.000Z",
|
|
288
|
+
* before: DocumentSnapshot.existing(ref, { title: "Draft" }),
|
|
289
|
+
* after: DocumentSnapshot.existing(ref, { title: "Final" }),
|
|
290
|
+
* });
|
|
291
|
+
* ```
|
|
292
|
+
*
|
|
293
|
+
* @see {@link updated} for declaring the trigger
|
|
294
|
+
* @see {@link serve} for running the event through the handler
|
|
295
|
+
* @see {@link Updated} for the event it builds
|
|
296
|
+
*
|
|
297
|
+
* @stability unstable
|
|
298
|
+
* @category constructors
|
|
299
|
+
* @since 0.3.0
|
|
300
|
+
*/
|
|
301
|
+
const updatedEvent = changeEvent;
|
|
302
|
+
/**
|
|
303
|
+
* Declares a trigger that runs when a document of `collection` is created,
|
|
304
|
+
* updated or deleted.
|
|
305
|
+
*
|
|
306
|
+
* **When to use**
|
|
307
|
+
*
|
|
308
|
+
* Use to handle every change to a collection's documents in one handler, such
|
|
309
|
+
* as keeping a copy or a count in sync. Prefer {@link created},
|
|
310
|
+
* {@link updated} or {@link deleted} when the handler acts on one change only.
|
|
311
|
+
*
|
|
312
|
+
* **Details**
|
|
313
|
+
*
|
|
314
|
+
* Its handler gets a {@link Written} event, whose `before` and `after` are
|
|
315
|
+
* `DocumentSnapshot`s: `before` is `Missing` on a create, and `after` is
|
|
316
|
+
* `Missing` on a delete. Narrow each with `DocumentSnapshot.isExisting` or
|
|
317
|
+
* `DocumentSnapshot.isMissing`.
|
|
318
|
+
*
|
|
319
|
+
* Firebase delivers each event at least once. Make the handler idempotent,
|
|
320
|
+
* keyed on the event's `id`.
|
|
321
|
+
*
|
|
322
|
+
* @example Telling a create, an update and a delete apart
|
|
323
|
+
* ```ts
|
|
324
|
+
* import { Effect, Schema } from "effect";
|
|
325
|
+
* import { Collection, DocumentSnapshot, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
326
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
327
|
+
*
|
|
328
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
329
|
+
*
|
|
330
|
+
* const OnPostWritten = DocumentTrigger.written("onPostWritten", Collection.make("posts", Post));
|
|
331
|
+
*
|
|
332
|
+
* const OnPostWrittenLive = DocumentTrigger.toLayer(OnPostWritten, (event) => {
|
|
333
|
+
* if (DocumentSnapshot.isMissing(event.after)) {
|
|
334
|
+
* return Effect.log(`Deleted ${event.ref.id}`);
|
|
335
|
+
* }
|
|
336
|
+
* const verb = DocumentSnapshot.isExisting(event.before) ? "Updated" : "Created";
|
|
337
|
+
* return Effect.flatMap(event.after.data, (post) => Effect.log(`${verb} ${post.title}`));
|
|
338
|
+
* });
|
|
339
|
+
* ```
|
|
340
|
+
*
|
|
341
|
+
* @see {@link created} for running on a create only, with the document always there
|
|
342
|
+
* @see {@link updated} for running on an update only, with both sides always there
|
|
343
|
+
* @see {@link deleted} for running on a delete only, with the last data always there
|
|
344
|
+
* @see {@link toLayer} for implementing the trigger
|
|
345
|
+
* @see {@link writtenEvent} for building its event in a test
|
|
346
|
+
* @see {@link FunctionGroup.make} for collecting Functions under one prefix
|
|
347
|
+
*
|
|
348
|
+
* @stability unstable
|
|
349
|
+
* @category constructors
|
|
350
|
+
* @since 0.3.0
|
|
351
|
+
*/
|
|
352
|
+
const written = (name, collection) => make({
|
|
353
|
+
kind,
|
|
354
|
+
name,
|
|
355
|
+
event: "written",
|
|
356
|
+
collection
|
|
357
|
+
});
|
|
358
|
+
/**
|
|
359
|
+
* Builds the event of a {@link written} trigger from the snapshots of the
|
|
360
|
+
* document before and after the write.
|
|
361
|
+
*
|
|
362
|
+
* **When to use**
|
|
363
|
+
*
|
|
364
|
+
* Use in a test, to run a handler through {@link serve} with an event of
|
|
365
|
+
* your own. The functions package builds its events with it too.
|
|
366
|
+
*
|
|
367
|
+
* **Details**
|
|
368
|
+
*
|
|
369
|
+
* Both snapshots are of the same document. The event's `ref` is the one of
|
|
370
|
+
* `after`, which a `Missing` snapshot carries too. Build a side that exists
|
|
371
|
+
* with `DocumentSnapshot.existing` and one that doesn't with
|
|
372
|
+
* `DocumentSnapshot.missing`.
|
|
373
|
+
*
|
|
374
|
+
* @example Building the event of a create for a test
|
|
375
|
+
* ```ts
|
|
376
|
+
* import { Schema } from "effect";
|
|
377
|
+
* import { Collection, DocumentSnapshot, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
378
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
379
|
+
*
|
|
380
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
381
|
+
*
|
|
382
|
+
* const Posts = Collection.make("posts", Post);
|
|
383
|
+
* const ref = Posts.doc(Posts.id.make("hello"));
|
|
384
|
+
*
|
|
385
|
+
* const event = DocumentTrigger.writtenEvent({
|
|
386
|
+
* id: "event-1",
|
|
387
|
+
* time: "2026-01-01T00:00:00.000Z",
|
|
388
|
+
* before: DocumentSnapshot.missing(ref),
|
|
389
|
+
* after: DocumentSnapshot.existing(ref, { title: "Hello" }),
|
|
390
|
+
* });
|
|
391
|
+
* ```
|
|
392
|
+
*
|
|
393
|
+
* @see {@link written} for declaring the trigger
|
|
394
|
+
* @see {@link serve} for running the event through the handler
|
|
395
|
+
* @see {@link Written} for the event it builds
|
|
396
|
+
*
|
|
397
|
+
* @stability unstable
|
|
398
|
+
* @category constructors
|
|
399
|
+
* @since 0.3.0
|
|
400
|
+
*/
|
|
401
|
+
const writtenEvent = changeEvent;
|
|
402
|
+
/**
|
|
403
|
+
* Implements a Document Trigger as a Layer.
|
|
404
|
+
*
|
|
405
|
+
* **When to use**
|
|
406
|
+
*
|
|
407
|
+
* Use to write the server side of a trigger. The Layer is what
|
|
408
|
+
* `Functions.make` and `Functions.group` from
|
|
409
|
+
* `@visiolab/effect-firebase-functions` serve, and what {@link serve} runs
|
|
410
|
+
* in a test.
|
|
411
|
+
*
|
|
412
|
+
* **Details**
|
|
413
|
+
*
|
|
414
|
+
* Takes the handler itself, or an Effect that builds it. The Effect runs
|
|
415
|
+
* once, when the Layer is built, so do per-instance setup there.
|
|
416
|
+
*
|
|
417
|
+
* For a trigger in a Function Group, pass the group and the member's name.
|
|
418
|
+
* Each group implements its members separately, so the Layer of the trigger
|
|
419
|
+
* on its own doesn't serve it in a group, and the Layer of one group's
|
|
420
|
+
* member doesn't serve it in another.
|
|
421
|
+
*
|
|
422
|
+
* The Layer requires what the handler needs on each event and what building
|
|
423
|
+
* it needs. Both are provided where the Layer is built, and shared by every
|
|
424
|
+
* event. Reading `snapshot.data` needs what the collection's model needs to
|
|
425
|
+
* decode.
|
|
426
|
+
*
|
|
427
|
+
* Firebase delivers each event at least once. Make the handler idempotent,
|
|
428
|
+
* keyed on the event's `id`.
|
|
429
|
+
*
|
|
430
|
+
* @example Building the handler once per instance
|
|
431
|
+
* ```ts
|
|
432
|
+
* import { Effect, Schema } from "effect";
|
|
433
|
+
* import { Collection, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
434
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
435
|
+
*
|
|
436
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
437
|
+
*
|
|
438
|
+
* const OnPostCreated = DocumentTrigger.created("onPostCreated", Collection.make("posts", Post));
|
|
439
|
+
*
|
|
440
|
+
* const OnPostCreatedLive = DocumentTrigger.toLayer(
|
|
441
|
+
* OnPostCreated,
|
|
442
|
+
* Effect.gen(function* () {
|
|
443
|
+
* const prefix = yield* Effect.succeed("New post");
|
|
444
|
+
* return (event) => Effect.log(`${prefix}: ${event.ref.id}`);
|
|
445
|
+
* }),
|
|
446
|
+
* );
|
|
447
|
+
* ```
|
|
448
|
+
*
|
|
449
|
+
* @example Implementing a trigger in a Function Group
|
|
450
|
+
* ```ts
|
|
451
|
+
* import { Effect, Schema } from "effect";
|
|
452
|
+
* import { Collection, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
453
|
+
* import { Callable, DocumentTrigger, FunctionGroup } from "@visiolab/effect-firebase/functions";
|
|
454
|
+
*
|
|
455
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
456
|
+
*
|
|
457
|
+
* const Publish = Callable.make("publish", { payload: { id: Schema.String } });
|
|
458
|
+
* const OnCreated = DocumentTrigger.created("onCreated", Collection.make("posts", Post));
|
|
459
|
+
*
|
|
460
|
+
* class Posts extends FunctionGroup.make("posts").add(Publish, OnCreated) {}
|
|
461
|
+
*
|
|
462
|
+
* // Serves `posts-onCreated`.
|
|
463
|
+
* const OnCreatedLive = DocumentTrigger.toLayer(Posts, "onCreated", (event) =>
|
|
464
|
+
* Effect.log(`New post: ${event.ref.id}`),
|
|
465
|
+
* );
|
|
466
|
+
* ```
|
|
467
|
+
*
|
|
468
|
+
* @see {@link created}, {@link updated}, {@link deleted} and {@link written} for declaring the trigger
|
|
469
|
+
* @see {@link serve} for running an event through the handler
|
|
470
|
+
* @see {@link Callable.toLayer} for implementing a Callable
|
|
471
|
+
* @see {@link FunctionGroup.make} for collecting Functions under one prefix
|
|
472
|
+
*
|
|
473
|
+
* @stability unstable
|
|
474
|
+
* @category constructors
|
|
475
|
+
* @since 0.3.0
|
|
476
|
+
*/
|
|
477
|
+
const toLayer = ((...args) => {
|
|
478
|
+
const [group, trigger] = target(args);
|
|
479
|
+
return toLayer$1(group?.identifier, trigger.name, args[group === void 0 ? 1 : 2]);
|
|
480
|
+
});
|
|
481
|
+
/**
|
|
482
|
+
* Runs events of a Document Trigger through its handler.
|
|
483
|
+
*
|
|
484
|
+
* **When to use**
|
|
485
|
+
*
|
|
486
|
+
* Use to test a trigger's handler in process, without the emulator and
|
|
487
|
+
* without `firebase-functions`: build an event with {@link createdEvent},
|
|
488
|
+
* {@link updatedEvent}, {@link deletedEvent} or {@link writtenEvent} and
|
|
489
|
+
* provide the Layer from {@link toLayer}. `Functions.make` from
|
|
490
|
+
* `@visiolab/effect-firebase-functions` runs every real event through it too.
|
|
491
|
+
*
|
|
492
|
+
* **Details**
|
|
493
|
+
*
|
|
494
|
+
* Requires the trigger's handler, which it reads once. Returns a function of
|
|
495
|
+
* the event, which fails with whatever the handler fails with.
|
|
496
|
+
*
|
|
497
|
+
* For a trigger in a Function Group, pass the group and the member's name:
|
|
498
|
+
* it then requires the handler from `toLayer(group, name, handler)`.
|
|
499
|
+
*
|
|
500
|
+
* @example Running an event in a test
|
|
501
|
+
* ```ts
|
|
502
|
+
* import { Effect, Schema } from "effect";
|
|
503
|
+
* import { Collection, DocumentSnapshot, FirestoreModel } from "@visiolab/effect-firebase/firestore";
|
|
504
|
+
* import { DocumentTrigger } from "@visiolab/effect-firebase/functions";
|
|
505
|
+
*
|
|
506
|
+
* class Post extends FirestoreModel.Class<Post>("Post")({ title: Schema.String }) {}
|
|
507
|
+
*
|
|
508
|
+
* const Posts = Collection.make("posts", Post);
|
|
509
|
+
* const OnPostCreated = DocumentTrigger.created("onPostCreated", Posts);
|
|
510
|
+
*
|
|
511
|
+
* const OnPostCreatedLive = DocumentTrigger.toLayer(OnPostCreated, (event) =>
|
|
512
|
+
* Effect.flatMap(event.snapshot.data, (post) => Effect.log(post.title)),
|
|
513
|
+
* );
|
|
514
|
+
*
|
|
515
|
+
* const program = DocumentTrigger.serve(OnPostCreated).pipe(
|
|
516
|
+
* Effect.flatMap((run) =>
|
|
517
|
+
* run(
|
|
518
|
+
* DocumentTrigger.createdEvent({
|
|
519
|
+
* id: "event-1",
|
|
520
|
+
* time: "2026-01-01T00:00:00.000Z",
|
|
521
|
+
* snapshot: DocumentSnapshot.existing(Posts.doc(Posts.id.make("hello")), {
|
|
522
|
+
* title: "Hello",
|
|
523
|
+
* }),
|
|
524
|
+
* }),
|
|
525
|
+
* ),
|
|
526
|
+
* ),
|
|
527
|
+
* Effect.provide(OnPostCreatedLive),
|
|
528
|
+
* );
|
|
529
|
+
* ```
|
|
530
|
+
*
|
|
531
|
+
* @see {@link toLayer} for providing the handler
|
|
532
|
+
* @see {@link createdEvent} for building the event of a `created` trigger
|
|
533
|
+
* @see {@link deletedEvent} for building the event of a `deleted` trigger
|
|
534
|
+
* @see {@link updatedEvent} for building the event of an `updated` trigger
|
|
535
|
+
* @see {@link writtenEvent} for building the event of a `written` trigger
|
|
536
|
+
* @see {@link Functions.make} for deploying the trigger through `firebase-functions`
|
|
537
|
+
* @see {@link Callable.serve} for running a call to a Callable
|
|
538
|
+
*
|
|
539
|
+
* @stability unstable
|
|
540
|
+
* @category serving
|
|
541
|
+
* @since 0.3.0
|
|
542
|
+
*/
|
|
543
|
+
const serve = ((...args) => serve$1(...target(args)));
|
|
544
|
+
/**
|
|
545
|
+
* Returns the {@link Deployment} of a Document Trigger: its deployed name and
|
|
546
|
+
* its document path pattern. A building block of the functions package. Most
|
|
547
|
+
* apps don't need it.
|
|
548
|
+
*
|
|
549
|
+
* **When to use**
|
|
550
|
+
*
|
|
551
|
+
* Use when deploying triggers with a transport of your own. `Functions`
|
|
552
|
+
* already uses it.
|
|
553
|
+
*
|
|
554
|
+
* **Details**
|
|
555
|
+
*
|
|
556
|
+
* Pass the trigger for one in no group, or a Function Group and a trigger
|
|
557
|
+
* member's name for one in a group, which is deployed as `<group>-<name>`.
|
|
558
|
+
*
|
|
559
|
+
* @see {@link Callable.deployment} for where a Callable is served
|
|
560
|
+
*
|
|
561
|
+
* @stability unstable
|
|
562
|
+
* @category serving
|
|
563
|
+
* @since 0.3.0
|
|
564
|
+
*/
|
|
565
|
+
const deployment = ((...args) => deployment$1(...target(args)));
|
|
566
|
+
export { DocumentTrigger_exports, created, createdEvent, deleted, deletedEvent, deployment, serve, toLayer, updated, updatedEvent, written, writtenEvent };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { HandlerTypeId, NoGroupTypeId } from "./internal/firebaseFunction.mjs";
|
|
2
|
+
declare namespace FirebaseFunction_d_exports {
|
|
3
|
+
export { Any, FirebaseFunction, Handler, HandlerFor, NoGroup };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A Function: a server function's kind and its name.
|
|
7
|
+
*
|
|
8
|
+
* **Details**
|
|
9
|
+
*
|
|
10
|
+
* The name is the Function's identity. A Function in no group is deployed
|
|
11
|
+
* under its name, and a member of a group under `<group>-<name>`. It is a
|
|
12
|
+
* literal type that exports and group members are keyed on.
|
|
13
|
+
*
|
|
14
|
+
* The kind says what runs the Function, such as `"Callable"`, and decides how
|
|
15
|
+
* it is served and deployed.
|
|
16
|
+
*
|
|
17
|
+
* @stability unstable
|
|
18
|
+
* @category models
|
|
19
|
+
* @since 0.3.0
|
|
20
|
+
*/
|
|
21
|
+
export interface FirebaseFunction<out Kind extends string, out Name extends string> {
|
|
22
|
+
/** What runs the Function, such as `"Callable"`. */
|
|
23
|
+
readonly kind: Kind;
|
|
24
|
+
/** The Function's name, which a Function in no group is deployed under. */
|
|
25
|
+
readonly name: Name;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Any {@link FirebaseFunction}, whatever its kind and name.
|
|
29
|
+
*
|
|
30
|
+
* @stability unstable
|
|
31
|
+
* @category models
|
|
32
|
+
* @since 0.3.0
|
|
33
|
+
*/
|
|
34
|
+
export interface Any extends FirebaseFunction<string, string> {}
|
|
35
|
+
/**
|
|
36
|
+
* Marks the {@link Handler} of a Function in no group.
|
|
37
|
+
*
|
|
38
|
+
* @stability unstable
|
|
39
|
+
* @category models
|
|
40
|
+
* @since 0.3.0
|
|
41
|
+
*/
|
|
42
|
+
export interface NoGroup {
|
|
43
|
+
readonly [NoGroupTypeId]: typeof NoGroupTypeId;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The service that holds the handler of the Function `Name`, as served in
|
|
47
|
+
* `Group`, whatever its kind.
|
|
48
|
+
*
|
|
49
|
+
* **Details**
|
|
50
|
+
*
|
|
51
|
+
* A handler is keyed by its group and its name, so the handler of `greet` in
|
|
52
|
+
* no group is `Handler<NoGroup, "greet">`, and that of `create` in the group
|
|
53
|
+
* `users` is `Handler<"users", "create">`. A Layer that serves a Function must
|
|
54
|
+
* provide its handler under exactly that key. Each kind's `toLayer`, such as
|
|
55
|
+
* {@link Callable.toLayer}, builds such a Layer.
|
|
56
|
+
*
|
|
57
|
+
* @see {@link HandlerFor} for the handler of a Function in no group
|
|
58
|
+
*
|
|
59
|
+
* @stability unstable
|
|
60
|
+
* @category models
|
|
61
|
+
* @since 0.3.0
|
|
62
|
+
*/
|
|
63
|
+
export interface Handler<Group, Name extends string> {
|
|
64
|
+
readonly [HandlerTypeId]: {
|
|
65
|
+
readonly group: Group;
|
|
66
|
+
readonly name: Name;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The {@link Handler} of a Function in no group.
|
|
71
|
+
*
|
|
72
|
+
* @see {@link Handler} for the handler of a member of a group
|
|
73
|
+
*
|
|
74
|
+
* @stability unstable
|
|
75
|
+
* @category type-level
|
|
76
|
+
* @since 0.3.0
|
|
77
|
+
*/
|
|
78
|
+
export type HandlerFor<F extends Any> = Handler<NoGroup, F["name"]>;
|
|
79
|
+
export { FirebaseFunction_d_exports };
|