@visiolab/effect-firebase 0.0.0-stage → 0.3.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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -2
  3. package/dist/_virtual/_rolldown/runtime.mjs +12 -0
  4. package/dist/app/App.d.mts +27 -0
  5. package/dist/app/App.mjs +27 -0
  6. package/dist/app/index.d.mts +2 -0
  7. package/dist/app/index.mjs +1 -0
  8. package/dist/firestore/Collection.d.mts +423 -0
  9. package/dist/firestore/Collection.mjs +133 -0
  10. package/dist/firestore/CollectionGroup.d.mts +164 -0
  11. package/dist/firestore/CollectionGroup.mjs +84 -0
  12. package/dist/firestore/DocumentPath.d.mts +95 -0
  13. package/dist/firestore/DocumentPath.mjs +71 -0
  14. package/dist/firestore/DocumentSnapshot.d.mts +239 -0
  15. package/dist/firestore/DocumentSnapshot.mjs +134 -0
  16. package/dist/firestore/FieldValue.d.mts +332 -0
  17. package/dist/firestore/FieldValue.mjs +256 -0
  18. package/dist/firestore/Firestore.d.mts +1165 -0
  19. package/dist/firestore/Firestore.mjs +274 -0
  20. package/dist/firestore/FirestoreModel.d.mts +1232 -0
  21. package/dist/firestore/FirestoreModel.mjs +586 -0
  22. package/dist/firestore/FirestoreSchema.d.mts +567 -0
  23. package/dist/firestore/FirestoreSchema.mjs +419 -0
  24. package/dist/firestore/FirestoreValue.d.mts +145 -0
  25. package/dist/firestore/FirestoreValue.mjs +87 -0
  26. package/dist/firestore/GeoPoint.d.mts +90 -0
  27. package/dist/firestore/GeoPoint.mjs +75 -0
  28. package/dist/firestore/Patch.d.mts +73 -0
  29. package/dist/firestore/Patch.mjs +57 -0
  30. package/dist/firestore/QuerySnapshot.d.mts +107 -0
  31. package/dist/firestore/QuerySnapshot.mjs +43 -0
  32. package/dist/firestore/Timestamp.d.mts +273 -0
  33. package/dist/firestore/Timestamp.mjs +255 -0
  34. package/dist/firestore/index.d.mts +14 -0
  35. package/dist/firestore/index.mjs +14 -0
  36. package/dist/firestore/internal/collection.mjs +156 -0
  37. package/dist/firestore/internal/collectionGroup.mjs +64 -0
  38. package/dist/firestore/internal/documentPath.d.mts +4 -0
  39. package/dist/firestore/internal/documentPath.mjs +42 -0
  40. package/dist/firestore/internal/documentSnapshot.mjs +63 -0
  41. package/dist/firestore/internal/fieldValue.d.mts +11 -0
  42. package/dist/firestore/internal/fieldValue.mjs +88 -0
  43. package/dist/firestore/internal/firestore.mjs +145 -0
  44. package/dist/firestore/internal/firestoreError.d.mts +29 -0
  45. package/dist/firestore/internal/firestoreError.mjs +30 -0
  46. package/dist/firestore/internal/firestoreModel.mjs +719 -0
  47. package/dist/firestore/internal/firestoreSchema.mjs +123 -0
  48. package/dist/firestore/internal/firestoreValue.mjs +108 -0
  49. package/dist/firestore/internal/firestoreValueWalk.d.mts +58 -0
  50. package/dist/firestore/internal/firestoreValueWalk.mjs +223 -0
  51. package/dist/firestore/internal/geoPoint.d.mts +4 -0
  52. package/dist/firestore/internal/geoPoint.mjs +39 -0
  53. package/dist/firestore/internal/patch.mjs +19 -0
  54. package/dist/firestore/internal/querySnapshot.mjs +24 -0
  55. package/dist/firestore/internal/schemaAST.mjs +35 -0
  56. package/dist/firestore/internal/snapshotExtra.mjs +35 -0
  57. package/dist/firestore/internal/streamFromListener.mjs +12 -0
  58. package/dist/firestore/internal/timestamp.d.mts +4 -0
  59. package/dist/firestore/internal/timestamp.mjs +66 -0
  60. package/dist/firestore/internal/timestampSchema.mjs +31 -0
  61. package/dist/firestore/internal/transactionFromCallback.mjs +66 -0
  62. package/dist/functions/Callable.d.mts +654 -0
  63. package/dist/functions/Callable.mjs +450 -0
  64. package/dist/functions/CallableError.d.mts +297 -0
  65. package/dist/functions/CallableError.mjs +256 -0
  66. package/dist/functions/CallableMiddleware.d.mts +213 -0
  67. package/dist/functions/CallableMiddleware.mjs +52 -0
  68. package/dist/functions/CallableRequest.d.mts +166 -0
  69. package/dist/functions/CallableRequest.mjs +18 -0
  70. package/dist/functions/Caller.d.mts +103 -0
  71. package/dist/functions/Caller.mjs +115 -0
  72. package/dist/functions/DocumentTrigger.d.mts +795 -0
  73. package/dist/functions/DocumentTrigger.mjs +566 -0
  74. package/dist/functions/FirebaseFunction.d.mts +79 -0
  75. package/dist/functions/FirebaseFunction.mjs +4 -0
  76. package/dist/functions/FunctionGroup.d.mts +175 -0
  77. package/dist/functions/FunctionGroup.mjs +64 -0
  78. package/dist/functions/index.d.mts +9 -0
  79. package/dist/functions/index.mjs +9 -0
  80. package/dist/functions/internal/callable.mjs +167 -0
  81. package/dist/functions/internal/callableMiddleware.d.mts +19 -0
  82. package/dist/functions/internal/callableMiddleware.mjs +15 -0
  83. package/dist/functions/internal/callableRequest.mjs +6 -0
  84. package/dist/functions/internal/documentTrigger.d.mts +10 -0
  85. package/dist/functions/internal/documentTrigger.mjs +73 -0
  86. package/dist/functions/internal/firebaseFunction.d.mts +5 -0
  87. package/dist/functions/internal/firebaseFunction.mjs +24 -0
  88. package/dist/functions/internal/functionGroup.mjs +36 -0
  89. package/package.json +66 -3
  90. package/src/app/App.ts +24 -0
  91. package/src/app/index.ts +7 -0
  92. package/src/firestore/Collection.ts +520 -0
  93. package/src/firestore/CollectionGroup.ts +245 -0
  94. package/src/firestore/DocumentPath.ts +114 -0
  95. package/src/firestore/DocumentSnapshot.ts +308 -0
  96. package/src/firestore/FieldValue.ts +375 -0
  97. package/src/firestore/Firestore.ts +1432 -0
  98. package/src/firestore/FirestoreModel.ts +1884 -0
  99. package/src/firestore/FirestoreSchema.ts +643 -0
  100. package/src/firestore/FirestoreValue.ts +207 -0
  101. package/src/firestore/GeoPoint.ts +105 -0
  102. package/src/firestore/Patch.ts +117 -0
  103. package/src/firestore/QuerySnapshot.ts +150 -0
  104. package/src/firestore/Timestamp.ts +302 -0
  105. package/src/firestore/index.ts +67 -0
  106. package/src/firestore/internal/collection.ts +246 -0
  107. package/src/firestore/internal/collectionGroup.ts +81 -0
  108. package/src/firestore/internal/documentPath.ts +53 -0
  109. package/src/firestore/internal/documentSnapshot.ts +117 -0
  110. package/src/firestore/internal/fieldValue.ts +119 -0
  111. package/src/firestore/internal/firestore.ts +322 -0
  112. package/src/firestore/internal/firestoreError.ts +36 -0
  113. package/src/firestore/internal/firestoreModel.ts +1242 -0
  114. package/src/firestore/internal/firestoreSchema.ts +218 -0
  115. package/src/firestore/internal/firestoreValue.ts +202 -0
  116. package/src/firestore/internal/firestoreValueWalk.ts +349 -0
  117. package/src/firestore/internal/geoPoint.ts +59 -0
  118. package/src/firestore/internal/patch.ts +21 -0
  119. package/src/firestore/internal/querySnapshot.ts +39 -0
  120. package/src/firestore/internal/schemaAST.ts +83 -0
  121. package/src/firestore/internal/snapshotExtra.ts +47 -0
  122. package/src/firestore/internal/streamFromListener.ts +27 -0
  123. package/src/firestore/internal/timestamp.ts +119 -0
  124. package/src/firestore/internal/timestampSchema.ts +42 -0
  125. package/src/firestore/internal/transactionFromCallback.ts +106 -0
  126. package/src/functions/Callable.ts +855 -0
  127. package/src/functions/CallableError.ts +348 -0
  128. package/src/functions/CallableMiddleware.ts +279 -0
  129. package/src/functions/CallableRequest.ts +207 -0
  130. package/src/functions/Caller.ts +141 -0
  131. package/src/functions/DocumentTrigger.ts +927 -0
  132. package/src/functions/FirebaseFunction.ts +96 -0
  133. package/src/functions/FunctionGroup.ts +225 -0
  134. package/src/functions/index.ts +62 -0
  135. package/src/functions/internal/callable.ts +272 -0
  136. package/src/functions/internal/callableMiddleware.ts +54 -0
  137. package/src/functions/internal/callableRequest.ts +8 -0
  138. package/src/functions/internal/documentTrigger.ts +143 -0
  139. package/src/functions/internal/firebaseFunction.ts +58 -0
  140. 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 };
@@ -0,0 +1,4 @@
1
+ import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
2
+ // src/functions/FirebaseFunction.ts
3
+ var FirebaseFunction_exports = /* @__PURE__ */ __exportAll({});
4
+ export { FirebaseFunction_exports };