@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.
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 +72 -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,54 @@
1
+ /** @internal */
2
+ import { Context, type Effect, type Schema } from "effect";
3
+
4
+ /** @internal */
5
+ export const TypeId = "~@visiolab/effect-firebase/functions/CallableMiddleware";
6
+
7
+ /**
8
+ * A middleware's key as the chain reads it, with its types erased.
9
+ *
10
+ * @internal
11
+ */
12
+ export interface Key extends Context.Key<never, Implementation> {
13
+ readonly [TypeId]: typeof TypeId;
14
+ readonly error: ReadonlySet<Schema.Top>;
15
+ }
16
+
17
+ /**
18
+ * A middleware's implementation as the chain runs it.
19
+ *
20
+ * @internal
21
+ */
22
+ export type Implementation = (
23
+ effect: Effect.Effect<unknown, unknown>,
24
+ options: { readonly callable: unknown },
25
+ ) => Effect.Effect<unknown, unknown>;
26
+
27
+ /**
28
+ * The middleware attached to a Callable, as a union, from its phantom
29
+ * `~Middleware` field.
30
+ *
31
+ * @internal
32
+ */
33
+ export type Attached<X> = X extends { readonly "~Middleware": infer M } ? M : never;
34
+
35
+ /**
36
+ * What the middleware attached to a Callable still requires, from its phantom
37
+ * `~MiddlewareServices` field.
38
+ *
39
+ * @internal
40
+ */
41
+ export type AttachedServices<X> = X extends { readonly "~MiddlewareServices": infer R } ? R : never;
42
+
43
+ /** @internal */
44
+ export const Service = (
45
+ id: string,
46
+ options?: { readonly error?: Schema.Top | ReadonlyArray<Schema.Top> | undefined },
47
+ ) => {
48
+ class Service extends Context.Service<Service, any>()(id) {}
49
+ const self = Service as any;
50
+ self[TypeId] = TypeId;
51
+ const error = options?.error;
52
+ self.error = new Set(error === undefined ? [] : Array.isArray(error) ? error : [error]);
53
+ return self;
54
+ };
@@ -0,0 +1,8 @@
1
+ /** @internal */
2
+ import { Context } from "effect";
3
+ import type * as Public from "../CallableRequest.ts";
4
+
5
+ /** @internal */
6
+ export const CallableRequest = Context.Service<Public.CallableRequest>(
7
+ "@visiolab/effect-firebase/functions/CallableRequest",
8
+ );
@@ -0,0 +1,143 @@
1
+ /** @internal */
2
+ import { Context, Effect, Layer, Pipeable } from "effect";
3
+ import type * as Collection from "../../firestore/Collection.ts";
4
+ import type * as DocumentSnapshot from "../../firestore/DocumentSnapshot.ts";
5
+ import * as FirebaseFunction from "./firebaseFunction.ts";
6
+
7
+ /** @internal */
8
+ export const TypeId = "~@visiolab/effect-firebase/functions/DocumentTrigger";
9
+
10
+ /** @internal */
11
+ export const kind = "DocumentTrigger";
12
+
13
+ /**
14
+ * The changes to a document a trigger can listen to.
15
+ *
16
+ * @internal
17
+ */
18
+ export type EventKind = "created" | "deleted" | "updated" | "written";
19
+
20
+ /** @internal */
21
+ export interface Fields extends FirebaseFunction.Fields {
22
+ readonly kind: typeof kind;
23
+ readonly name: string;
24
+ readonly event: EventKind;
25
+ readonly collection: Collection.Any;
26
+ }
27
+
28
+ const Proto = {
29
+ [TypeId]: TypeId,
30
+ pipe() {
31
+ return Pipeable.pipeArguments(this, arguments);
32
+ },
33
+ };
34
+
35
+ /** @internal */
36
+ export const make = (fields: Fields): Fields => Object.assign(Object.create(Proto), fields);
37
+
38
+ /** @internal */
39
+ export const isDocumentTrigger = (u: unknown): u is Fields =>
40
+ typeof u === "object" && u !== null && TypeId in u;
41
+
42
+ /**
43
+ * A handler as it sits in the context: the services it was built with are
44
+ * already provided, so it needs only those of the event.
45
+ *
46
+ * @internal
47
+ */
48
+ export type HandlerService = (event: unknown) => Effect.Effect<void, unknown>;
49
+
50
+ /**
51
+ * What `toLayer` takes, with the types its signature has already checked
52
+ * erased.
53
+ *
54
+ * @internal
55
+ */
56
+ export type HandlerInput = HandlerService | Effect.Effect<HandlerService>;
57
+
58
+ /**
59
+ * The key of the handler of the Document Trigger `name` in `group`, or in no
60
+ * group.
61
+ *
62
+ * @internal
63
+ */
64
+ export const handlerKey = (group: string | undefined, name: string) =>
65
+ FirebaseFunction.handlerKey<HandlerService>(group, name);
66
+
67
+ /** @internal */
68
+ export const toLayer = (group: string | undefined, name: string, handler: HandlerInput) =>
69
+ Layer.effect(
70
+ handlerKey(group, name),
71
+ Effect.gen(function* () {
72
+ const run = Effect.isEffect(handler) ? yield* handler : handler;
73
+ // The services the Layer was built with, under those of the event.
74
+ const built = yield* Effect.context<never>();
75
+ return (event: unknown) =>
76
+ Effect.updateContext(run(event), (call: Context.Context<never>) =>
77
+ Context.merge(built, call),
78
+ );
79
+ }),
80
+ );
81
+
82
+ /** @internal */
83
+ export const serve = (group: FirebaseFunction.Group | undefined, trigger: Fields) =>
84
+ Effect.service(handlerKey(group?.identifier, trigger.name));
85
+
86
+ /**
87
+ * The path pattern of the documents of `collection`, with a wildcard of its
88
+ * own for each ancestor id and for the document id:
89
+ * `users/{id0}/posts/{id1}`. The wildcards are only ever read back through
90
+ * the event's document path, so their names are free.
91
+ *
92
+ * @internal
93
+ */
94
+ export const documentPattern = (collection: Collection.Any): string =>
95
+ collection.path.map((segment, i) => `${segment}/{id${i}}`).join("/");
96
+
97
+ /** @internal */
98
+ export const deployment = (group: FirebaseFunction.Group | undefined, trigger: Fields) => ({
99
+ name: FirebaseFunction.deployedName(group, trigger),
100
+ document: documentPattern(trigger.collection),
101
+ });
102
+
103
+ /** @internal */
104
+ export const createdEvent = <C extends Collection.Any>(input: {
105
+ readonly id: string;
106
+ readonly time: string;
107
+ readonly snapshot: DocumentSnapshot.Existing<C>;
108
+ }) => ({
109
+ id: input.id,
110
+ time: input.time,
111
+ ref: input.snapshot.ref,
112
+ snapshot: input.snapshot,
113
+ });
114
+
115
+ /**
116
+ * A `deleted` event has the shape of a `created` one, with the document as it
117
+ * was just before it was deleted.
118
+ *
119
+ * @internal
120
+ */
121
+ export const deletedEvent = createdEvent;
122
+
123
+ /**
124
+ * The event of a change with a document on each side. Both sides are at the
125
+ * same reference; `ref` is taken from `after`.
126
+ *
127
+ * @internal
128
+ */
129
+ export const changeEvent = <
130
+ C extends Collection.Any,
131
+ S extends DocumentSnapshot.DocumentSnapshot<C>,
132
+ >(input: {
133
+ readonly id: string;
134
+ readonly time: string;
135
+ readonly before: S;
136
+ readonly after: S;
137
+ }) => ({
138
+ id: input.id,
139
+ time: input.time,
140
+ ref: input.after.ref,
141
+ before: input.before,
142
+ after: input.after,
143
+ });
@@ -0,0 +1,58 @@
1
+ /** @internal */
2
+ import { Context } from "effect";
3
+
4
+ /** @internal */
5
+ export const TypeId = "~@visiolab/effect-firebase/functions/FirebaseFunction";
6
+
7
+ /** @internal */
8
+ export const NoGroupTypeId = "~@visiolab/effect-firebase/functions/FirebaseFunction/NoGroup";
9
+
10
+ /** @internal */
11
+ export const HandlerTypeId = "~@visiolab/effect-firebase/functions/FirebaseFunction/Handler";
12
+
13
+ /**
14
+ * What every kind of Function holds: its kind and its name.
15
+ *
16
+ * @internal
17
+ */
18
+ export interface Fields {
19
+ readonly kind: string;
20
+ readonly name: string;
21
+ }
22
+
23
+ /**
24
+ * The fields of a Function Group that a Function in it is served by.
25
+ *
26
+ * @internal
27
+ */
28
+ export interface Group {
29
+ readonly identifier: string;
30
+ }
31
+
32
+ /**
33
+ * The key of the handler of the Function `name` in `group`, or in no group,
34
+ * whatever its kind. A kind decides what it holds.
35
+ *
36
+ * Context keys are compared by their string, so every call with the same group
37
+ * and name reaches the same service. Deployed names can't contain `/`, so the
38
+ * two forms can't collide. Names are unique within a group, and a Function in
39
+ * no group is deployed under its name, so two kinds never share a key they
40
+ * could both be served under.
41
+ *
42
+ * @internal
43
+ */
44
+ export const handlerKey = <S>(group: string | undefined, name: string) =>
45
+ Context.Service<never, S>(
46
+ group === undefined
47
+ ? `@visiolab/effect-firebase/functions/Handler/${name}`
48
+ : `@visiolab/effect-firebase/functions/Handler/${group}/${name}`,
49
+ );
50
+
51
+ /**
52
+ * The name `fn` is deployed under: its own in no group, or `<group>-<name>`
53
+ * in `group`.
54
+ *
55
+ * @internal
56
+ */
57
+ export const deployedName = (group: Group | undefined, fn: Fields): string =>
58
+ group === undefined ? fn.name : `${group.identifier}-${fn.name}`;
@@ -0,0 +1,47 @@
1
+ /** @internal */
2
+ import { Pipeable } from "effect";
3
+ import type * as FirebaseFunction from "./firebaseFunction.ts";
4
+
5
+ /** @internal */
6
+ export const TypeId = "~@visiolab/effect-firebase/functions/FunctionGroup";
7
+
8
+ /** @internal */
9
+ export interface Fields {
10
+ readonly identifier: string;
11
+ readonly functions: Readonly<Record<string, FirebaseFunction.Fields>>;
12
+ }
13
+
14
+ /** @internal */
15
+ export const isFunctionGroup = (u: unknown): u is Fields =>
16
+ (typeof u === "function" || (typeof u === "object" && u !== null)) && TypeId in u;
17
+
18
+ const Proto = {
19
+ [TypeId]: TypeId,
20
+ add(this: Fields, ...toAdd: ReadonlyArray<FirebaseFunction.Fields>) {
21
+ const functions = { ...this.functions };
22
+ for (const fn of toAdd) {
23
+ if (Object.hasOwn(functions, fn.name)) {
24
+ throw new Error(
25
+ `The Function Group "${this.identifier}" already has a Function named "${fn.name}"`,
26
+ );
27
+ }
28
+ functions[fn.name] = fn;
29
+ }
30
+ return make({ identifier: this.identifier, functions });
31
+ },
32
+ pipe() {
33
+ return Pipeable.pipeArguments(this, arguments);
34
+ },
35
+ };
36
+
37
+ /**
38
+ * A function, so that a group can be the base of a class. Its `name` is the
39
+ * function's own, so the group's name is its `identifier`.
40
+ *
41
+ * @internal
42
+ */
43
+ export const make = (fields: Fields) => {
44
+ function FunctionGroup() {}
45
+ Object.setPrototypeOf(FunctionGroup, Proto);
46
+ return Object.assign(FunctionGroup, fields);
47
+ };