@visiolab/effect-firebase-client 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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -2
  3. package/dist/_virtual/_rolldown/runtime.mjs +12 -0
  4. package/dist/app/App.d.mts +117 -0
  5. package/dist/app/App.mjs +149 -0
  6. package/dist/app/App.mjs.map +1 -0
  7. package/dist/app/index.d.mts +2 -0
  8. package/dist/app/index.mjs +1 -0
  9. package/dist/app/internal/app.mjs +20 -0
  10. package/dist/app/internal/app.mjs.map +1 -0
  11. package/dist/firestore/ClientDocumentSnapshot.d.mts +106 -0
  12. package/dist/firestore/ClientDocumentSnapshot.mjs +86 -0
  13. package/dist/firestore/ClientDocumentSnapshot.mjs.map +1 -0
  14. package/dist/firestore/ClientFirestore.d.mts +331 -0
  15. package/dist/firestore/ClientFirestore.mjs +146 -0
  16. package/dist/firestore/ClientFirestore.mjs.map +1 -0
  17. package/dist/firestore/ClientFirestoreValue.d.mts +61 -0
  18. package/dist/firestore/ClientFirestoreValue.mjs +62 -0
  19. package/dist/firestore/ClientFirestoreValue.mjs.map +1 -0
  20. package/dist/firestore/ClientQuerySnapshot.d.mts +52 -0
  21. package/dist/firestore/ClientQuerySnapshot.mjs +58 -0
  22. package/dist/firestore/ClientQuerySnapshot.mjs.map +1 -0
  23. package/dist/firestore/index.d.mts +5 -0
  24. package/dist/firestore/index.mjs +5 -0
  25. package/dist/firestore/internal/firestore.mjs +158 -0
  26. package/dist/firestore/internal/firestore.mjs.map +1 -0
  27. package/dist/firestore/internal/firestoreValue.mjs +43 -0
  28. package/dist/firestore/internal/firestoreValue.mjs.map +1 -0
  29. package/dist/firestore/internal/snapshotMetadata.mjs +15 -0
  30. package/dist/firestore/internal/snapshotMetadata.mjs.map +1 -0
  31. package/dist/functions/CallableClient.d.mts +139 -0
  32. package/dist/functions/CallableClient.mjs +215 -0
  33. package/dist/functions/CallableClient.mjs.map +1 -0
  34. package/dist/functions/ClientFunctions.d.mts +112 -0
  35. package/dist/functions/ClientFunctions.mjs +105 -0
  36. package/dist/functions/ClientFunctions.mjs.map +1 -0
  37. package/dist/functions/index.d.mts +3 -0
  38. package/dist/functions/index.mjs +3 -0
  39. package/package.json +63 -3
  40. package/src/app/App.ts +163 -0
  41. package/src/app/index.ts +7 -0
  42. package/src/app/internal/app.ts +35 -0
  43. package/src/firestore/ClientDocumentSnapshot.ts +156 -0
  44. package/src/firestore/ClientFirestore.ts +410 -0
  45. package/src/firestore/ClientFirestoreValue.ts +94 -0
  46. package/src/firestore/ClientQuerySnapshot.ts +93 -0
  47. package/src/firestore/index.ts +30 -0
  48. package/src/firestore/internal/firestore.ts +264 -0
  49. package/src/firestore/internal/firestoreValue.ts +58 -0
  50. package/src/firestore/internal/snapshotMetadata.ts +14 -0
  51. package/src/functions/CallableClient.ts +296 -0
  52. package/src/functions/ClientFunctions.ts +149 -0
  53. package/src/functions/index.ts +15 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VisioLab GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,71 @@
1
- # Temporary Holding Version
1
+ # @visiolab/effect-firebase-client
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The [`@visiolab/effect-firebase`](https://github.com/VisioLab/effect-firebase/tree/main/packages/effect-firebase) services on the Firebase client SDK (`firebase`), for browsers. On a server, use [`@visiolab/effect-firebase-admin`](https://github.com/VisioLab/effect-firebase/tree/main/packages/admin) instead.
4
+
5
+ ```sh
6
+ pnpm add effect @visiolab/effect-firebase @visiolab/effect-firebase-client firebase
7
+ ```
8
+
9
+ ## App
10
+
11
+ `App` is the client SDK app as an Effect service. Every other service in this package is built on it.
12
+
13
+ `App.layer` initializes the app when the layer is built and deletes it when the layer's scope closes. It takes the arguments of `initializeApp(options, name)`. The options are required: they are the config the Firebase console gives a web app.
14
+
15
+ ```ts
16
+ import { Effect } from "effect";
17
+ import { App } from "@visiolab/effect-firebase-client/app";
18
+
19
+ const program = Effect.gen(function* () {
20
+ const app = yield* App.App;
21
+ yield* Effect.log(`Running against ${app.name}`);
22
+ });
23
+
24
+ program.pipe(
25
+ Effect.provide(App.layer({ apiKey: "<api key>", projectId: "my-project", appId: "<app id>" })),
26
+ );
27
+ ```
28
+
29
+ An app already registered under the same name is not deleted when the scope closes. The client SDK only hands that app back when it was initialized with the same options. To use an app initialized elsewhere, provide it directly:
30
+
31
+ ```ts
32
+ import { Layer } from "effect";
33
+ import { getApp } from "firebase/app";
34
+ import { App } from "@visiolab/effect-firebase-client/app";
35
+
36
+ const AppLive = Layer.succeed(App.App, getApp());
37
+ ```
38
+
39
+ ## Firestore
40
+
41
+ `ClientFirestore.layer` provides one service under two keys: the portable `Firestore`, which code that runs on either SDK asks for, and `ClientFirestore`, which adds what only the client SDK can do. Both reach the same database:
42
+
43
+ ```ts
44
+ import { Layer } from "effect";
45
+ import { persistentLocalCache } from "firebase/firestore";
46
+ import { App } from "@visiolab/effect-firebase-client/app";
47
+ import { ClientFirestore } from "@visiolab/effect-firebase-client/firestore";
48
+
49
+ const FirestoreLive = ClientFirestore.layer({
50
+ localCache: persistentLocalCache(),
51
+ emulator: import.meta.env.DEV ? { host: "127.0.0.1", port: 8080 } : undefined,
52
+ }).pipe(
53
+ Layer.provide(App.layer({ apiKey: "<api key>", projectId: "my-project", appId: "<app id>" })),
54
+ );
55
+ ```
56
+
57
+ What `ClientFirestore` adds:
58
+
59
+ - **Read sources.** `getDoc` and `getDocs` take `{ source: "server" }` or `{ source: "cache" }` to read from one side alone.
60
+ - **Listen options.** `streamDoc` and `streamDocs` take `includeMetadataChanges` and a `source`.
61
+ - **Snapshot metadata.** Every snapshot carries `metadata`, with `fromCache` and `hasPendingWrites`, as `ClientDocumentSnapshot` and `ClientQuerySnapshot` describe.
62
+
63
+ Where it behaves differently from the Admin SDK's:
64
+
65
+ - **The emulator is a layer option**, connected before the database is first used, not an environment variable.
66
+ - **Writes wait for the server.** A write made offline is applied to the local cache at once, but only succeeds once the server acknowledges it. Interrupting it, or timing it out, does not take it back: the SDK still sends it when it can.
67
+ - **Pending server timestamps are estimated.** A field written with a server timestamp the server has not settled yet reads as the local clock's estimate, not `null`, so it decodes as a timestamp.
68
+ - **Error codes are always named**, such as `permission-denied`.
69
+ - **Transactions read one document at a time.** The client SDK's transactions cannot read a collection.
70
+
71
+ `ClientFirestore.instance` is the client SDK's own `Firestore`, for what the service does not wrap, such as `disableNetwork` and `enableNetwork`. `ClientFirestoreValue` maps between Firestore Values and the client SDK's values, to read or write a model through it.
@@ -0,0 +1,12 @@
1
+ // \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ export { __exportAll };
@@ -0,0 +1,117 @@
1
+ import { Context, Effect, Layer, Schema } from "effect";
2
+ import * as Client from "firebase/app";
3
+ declare namespace App_d_exports {
4
+ export { App, AppError, layer, make };
5
+ }
6
+ /**
7
+ * A Firebase client SDK app: the SDK's own `FirebaseApp`.
8
+ *
9
+ * @stability unstable
10
+ * @category models
11
+ * @since 0.1.0
12
+ */
13
+ export interface App extends Client.FirebaseApp {}
14
+ /**
15
+ * Service key for the Firebase client SDK app.
16
+ *
17
+ * **When to use**
18
+ *
19
+ * Use to provide an app initialized elsewhere, such as one from `getApp()`,
20
+ * with `Layer.succeed`. Nothing deletes an app provided this way.
21
+ *
22
+ * @example Providing an app initialized elsewhere
23
+ * ```ts
24
+ * import { Layer } from "effect";
25
+ * import { getApp } from "firebase/app";
26
+ * import { App } from "@visiolab/effect-firebase-client/app";
27
+ *
28
+ * const AppLive = Layer.succeed(App.App, getApp());
29
+ * ```
30
+ *
31
+ * @see {@link layer} for initializing the app for the lifetime of a layer
32
+ *
33
+ * @stability unstable
34
+ * @category services
35
+ * @since 0.1.0
36
+ */
37
+ export declare const App: Context.Service<App, App>;
38
+ declare const AppError_base: Schema.Class<AppError, Schema.TaggedStruct<"AppError", {
39
+ readonly message: Schema.String;
40
+ readonly cause: Schema.optional<Schema.Defect>;
41
+ }>, import("effect/Cause").YieldableError & {
42
+ readonly brand: unique symbol;
43
+ }>;
44
+ /**
45
+ * Fails {@link make} and {@link layer} when the client SDK refuses to
46
+ * initialize the app, with what it threw as the `cause`.
47
+ *
48
+ * @stability unstable
49
+ * @category errors
50
+ * @since 0.1.0
51
+ */
52
+ export declare class AppError extends AppError_base {}
53
+ /**
54
+ * Initializes a Firebase client SDK app, and deletes it again when the
55
+ * surrounding scope closes.
56
+ *
57
+ * **When to use**
58
+ *
59
+ * Use to build the app inside an effect of your own. Most programs provide it
60
+ * with {@link layer} instead.
61
+ *
62
+ * **Details**
63
+ *
64
+ * Takes the arguments of `initializeApp(options, name)`. Unlike the Admin SDK's,
65
+ * the options are required: they are the config the Firebase console gives a
66
+ * web app, which the client SDK only finds on its own when served from
67
+ * Firebase Hosting.
68
+ *
69
+ * An app already registered under the same name is not deleted when the scope
70
+ * closes. The client SDK only hands back that app when it was initialized with
71
+ * the same options, and throws otherwise.
72
+ *
73
+ * Fails with an {@link AppError} when the client SDK refuses to initialize the
74
+ * app. A failure to delete the app is logged as a warning, not raised.
75
+ *
76
+ * @see {@link layer} for the same as a layer
77
+ *
78
+ * @stability unstable
79
+ * @category constructors
80
+ * @since 0.1.0
81
+ */
82
+ export declare const make: (options: Client.FirebaseOptions, name?: string | undefined) => Effect.Effect<App, AppError, import("effect/Scope").Scope>;
83
+ /**
84
+ * A layer that initializes a Firebase client SDK app for the lifetime of the
85
+ * layer.
86
+ *
87
+ * **When to use**
88
+ *
89
+ * Use when this program owns the app. Where something else already initialized
90
+ * it, provide that app as {@link App} instead.
91
+ *
92
+ * **Details**
93
+ *
94
+ * Takes the arguments of `initializeApp(options, name)`.
95
+ *
96
+ * @example Initializing the app from the console's config
97
+ * ```ts
98
+ * import { App } from "@visiolab/effect-firebase-client/app";
99
+ *
100
+ * const AppLive = App.layer({
101
+ * apiKey: "<api key>",
102
+ * authDomain: "my-project.firebaseapp.com",
103
+ * projectId: "my-project",
104
+ * appId: "<app id>",
105
+ * });
106
+ * ```
107
+ *
108
+ * @see {@link make} for how the app is initialized and torn down
109
+ * @see {@link App} for providing an app initialized elsewhere
110
+ *
111
+ * @stability unstable
112
+ * @category layers
113
+ * @since 0.1.0
114
+ */
115
+ export declare const layer: (options: Client.FirebaseOptions, name?: string) => Layer.Layer<App, AppError>;
116
+ export { App_d_exports };
117
+ //# sourceMappingURL=App.d.mts.map
@@ -0,0 +1,149 @@
1
+ import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
2
+ import { initialize, release } from "./internal/app.mjs";
3
+ import { Context, Effect, Layer, Schema } from "effect";
4
+ // src/app/App.ts
5
+ /**
6
+ * The Firebase client SDK app as an Effect service.
7
+ *
8
+ * Every other service in this package, such as
9
+ * {@link ClientFirestore.ClientFirestore}, is built on the {@link App} in
10
+ * context. Provide it with {@link layer}, or hand it an app initialized
11
+ * elsewhere.
12
+ *
13
+ * @example Initializing the app for a program
14
+ * ```ts
15
+ * import { Effect } from "effect";
16
+ * import { App } from "@visiolab/effect-firebase-client/app";
17
+ *
18
+ * const program = Effect.gen(function* () {
19
+ * const app = yield* App.App;
20
+ * yield* Effect.log(`Running against ${app.name}`);
21
+ * });
22
+ *
23
+ * program.pipe(
24
+ * Effect.provide(App.layer({ apiKey: "<api key>", projectId: "my-project", appId: "<app id>" })),
25
+ * );
26
+ * ```
27
+ *
28
+ * @see [Add Firebase to your JavaScript project](https://firebase.google.com/docs/web/setup)
29
+ *
30
+ * @stability unstable
31
+ * @since 0.1.0
32
+ */
33
+ var App_exports = /* @__PURE__ */ __exportAll({
34
+ App: () => App,
35
+ AppError: () => AppError,
36
+ layer: () => layer,
37
+ make: () => make
38
+ });
39
+ /**
40
+ * Service key for the Firebase client SDK app.
41
+ *
42
+ * **When to use**
43
+ *
44
+ * Use to provide an app initialized elsewhere, such as one from `getApp()`,
45
+ * with `Layer.succeed`. Nothing deletes an app provided this way.
46
+ *
47
+ * @example Providing an app initialized elsewhere
48
+ * ```ts
49
+ * import { Layer } from "effect";
50
+ * import { getApp } from "firebase/app";
51
+ * import { App } from "@visiolab/effect-firebase-client/app";
52
+ *
53
+ * const AppLive = Layer.succeed(App.App, getApp());
54
+ * ```
55
+ *
56
+ * @see {@link layer} for initializing the app for the lifetime of a layer
57
+ *
58
+ * @stability unstable
59
+ * @category services
60
+ * @since 0.1.0
61
+ */
62
+ const App = Context.Service("@visiolab/effect-firebase-client/app/App");
63
+ /**
64
+ * Fails {@link make} and {@link layer} when the client SDK refuses to
65
+ * initialize the app, with what it threw as the `cause`.
66
+ *
67
+ * @stability unstable
68
+ * @category errors
69
+ * @since 0.1.0
70
+ */
71
+ var AppError = class extends Schema.TaggedError()("AppError", {
72
+ message: Schema.String,
73
+ cause: Schema.optional(Schema.Defect())
74
+ }) {};
75
+ /**
76
+ * Initializes a Firebase client SDK app, and deletes it again when the
77
+ * surrounding scope closes.
78
+ *
79
+ * **When to use**
80
+ *
81
+ * Use to build the app inside an effect of your own. Most programs provide it
82
+ * with {@link layer} instead.
83
+ *
84
+ * **Details**
85
+ *
86
+ * Takes the arguments of `initializeApp(options, name)`. Unlike the Admin SDK's,
87
+ * the options are required: they are the config the Firebase console gives a
88
+ * web app, which the client SDK only finds on its own when served from
89
+ * Firebase Hosting.
90
+ *
91
+ * An app already registered under the same name is not deleted when the scope
92
+ * closes. The client SDK only hands back that app when it was initialized with
93
+ * the same options, and throws otherwise.
94
+ *
95
+ * Fails with an {@link AppError} when the client SDK refuses to initialize the
96
+ * app. A failure to delete the app is logged as a warning, not raised.
97
+ *
98
+ * @see {@link layer} for the same as a layer
99
+ *
100
+ * @stability unstable
101
+ * @category constructors
102
+ * @since 0.1.0
103
+ */
104
+ const make = Effect.fn("App.make")(function* (options, name) {
105
+ const { app } = yield* Effect.acquireRelease(Effect.try({
106
+ try: () => initialize(options, name),
107
+ catch: (cause) => new AppError({
108
+ message: "Failed to initialize the Firebase client SDK app",
109
+ cause
110
+ })
111
+ }), release);
112
+ return app;
113
+ });
114
+ /**
115
+ * A layer that initializes a Firebase client SDK app for the lifetime of the
116
+ * layer.
117
+ *
118
+ * **When to use**
119
+ *
120
+ * Use when this program owns the app. Where something else already initialized
121
+ * it, provide that app as {@link App} instead.
122
+ *
123
+ * **Details**
124
+ *
125
+ * Takes the arguments of `initializeApp(options, name)`.
126
+ *
127
+ * @example Initializing the app from the console's config
128
+ * ```ts
129
+ * import { App } from "@visiolab/effect-firebase-client/app";
130
+ *
131
+ * const AppLive = App.layer({
132
+ * apiKey: "<api key>",
133
+ * authDomain: "my-project.firebaseapp.com",
134
+ * projectId: "my-project",
135
+ * appId: "<app id>",
136
+ * });
137
+ * ```
138
+ *
139
+ * @see {@link make} for how the app is initialized and torn down
140
+ * @see {@link App} for providing an app initialized elsewhere
141
+ *
142
+ * @stability unstable
143
+ * @category layers
144
+ * @since 0.1.0
145
+ */
146
+ const layer = (options, name) => Layer.effect(App, make(options, name));
147
+ export { App, AppError, App_exports, layer, make };
148
+
149
+ //# sourceMappingURL=App.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.mjs","names":["internalApp.initialize","internalApp.release"],"sources":["../../src/app/App.ts"],"sourcesContent":["/**\n * The Firebase client SDK app as an Effect service.\n *\n * Every other service in this package, such as\n * {@link ClientFirestore.ClientFirestore}, is built on the {@link App} in\n * context. Provide it with {@link layer}, or hand it an app initialized\n * elsewhere.\n *\n * @example Initializing the app for a program\n * ```ts\n * import { Effect } from \"effect\";\n * import { App } from \"@visiolab/effect-firebase-client/app\";\n *\n * const program = Effect.gen(function* () {\n * const app = yield* App.App;\n * yield* Effect.log(`Running against ${app.name}`);\n * });\n *\n * program.pipe(\n * Effect.provide(App.layer({ apiKey: \"<api key>\", projectId: \"my-project\", appId: \"<app id>\" })),\n * );\n * ```\n *\n * @see [Add Firebase to your JavaScript project](https://firebase.google.com/docs/web/setup)\n *\n * @stability unstable\n * @since 0.1.0\n */\nimport { Context, Effect, Layer, Schema } from \"effect\";\nimport type * as Client from \"firebase/app\";\n// Only the module's documentation links to it.\n// oxlint-disable-next-line no-unused-vars\nimport type * as ClientFirestore from \"../firestore/ClientFirestore.ts\";\nimport * as internalApp from \"./internal/app.ts\";\n\n/**\n * A Firebase client SDK app: the SDK's own `FirebaseApp`.\n *\n * @stability unstable\n * @category models\n * @since 0.1.0\n */\nexport interface App extends Client.FirebaseApp {}\n\n/**\n * Service key for the Firebase client SDK app.\n *\n * **When to use**\n *\n * Use to provide an app initialized elsewhere, such as one from `getApp()`,\n * with `Layer.succeed`. Nothing deletes an app provided this way.\n *\n * @example Providing an app initialized elsewhere\n * ```ts\n * import { Layer } from \"effect\";\n * import { getApp } from \"firebase/app\";\n * import { App } from \"@visiolab/effect-firebase-client/app\";\n *\n * const AppLive = Layer.succeed(App.App, getApp());\n * ```\n *\n * @see {@link layer} for initializing the app for the lifetime of a layer\n *\n * @stability unstable\n * @category services\n * @since 0.1.0\n */\nexport const App = Context.Service<App>(\"@visiolab/effect-firebase-client/app/App\");\n\n/**\n * Fails {@link make} and {@link layer} when the client SDK refuses to\n * initialize the app, with what it threw as the `cause`.\n *\n * @stability unstable\n * @category errors\n * @since 0.1.0\n */\nexport class AppError extends Schema.TaggedError<AppError, { readonly brand: unique symbol }>()(\n \"AppError\",\n {\n message: Schema.String,\n cause: Schema.optional(Schema.Defect()),\n },\n) {}\n\n/**\n * Initializes a Firebase client SDK app, and deletes it again when the\n * surrounding scope closes.\n *\n * **When to use**\n *\n * Use to build the app inside an effect of your own. Most programs provide it\n * with {@link layer} instead.\n *\n * **Details**\n *\n * Takes the arguments of `initializeApp(options, name)`. Unlike the Admin SDK's,\n * the options are required: they are the config the Firebase console gives a\n * web app, which the client SDK only finds on its own when served from\n * Firebase Hosting.\n *\n * An app already registered under the same name is not deleted when the scope\n * closes. The client SDK only hands back that app when it was initialized with\n * the same options, and throws otherwise.\n *\n * Fails with an {@link AppError} when the client SDK refuses to initialize the\n * app. A failure to delete the app is logged as a warning, not raised.\n *\n * @see {@link layer} for the same as a layer\n *\n * @stability unstable\n * @category constructors\n * @since 0.1.0\n */\nexport const make = Effect.fn(\"App.make\")(function* (\n options: Client.FirebaseOptions,\n name?: string,\n) {\n const { app } = yield* Effect.acquireRelease(\n Effect.try({\n try: () => internalApp.initialize(options, name),\n catch: (cause) =>\n new AppError({ message: \"Failed to initialize the Firebase client SDK app\", cause }),\n }),\n internalApp.release,\n );\n return app;\n});\n\n/**\n * A layer that initializes a Firebase client SDK app for the lifetime of the\n * layer.\n *\n * **When to use**\n *\n * Use when this program owns the app. Where something else already initialized\n * it, provide that app as {@link App} instead.\n *\n * **Details**\n *\n * Takes the arguments of `initializeApp(options, name)`.\n *\n * @example Initializing the app from the console's config\n * ```ts\n * import { App } from \"@visiolab/effect-firebase-client/app\";\n *\n * const AppLive = App.layer({\n * apiKey: \"<api key>\",\n * authDomain: \"my-project.firebaseapp.com\",\n * projectId: \"my-project\",\n * appId: \"<app id>\",\n * });\n * ```\n *\n * @see {@link make} for how the app is initialized and torn down\n * @see {@link App} for providing an app initialized elsewhere\n *\n * @stability unstable\n * @category layers\n * @since 0.1.0\n */\nexport const layer = (options: Client.FirebaseOptions, name?: string): Layer.Layer<App, AppError> =>\n Layer.effect(App, make(options, name));\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEA,MAAa,MAAM,QAAQ,QAAa,0CAA0C;;;;;;;;;AAUlF,IAAa,WAAb,cAA8B,OAAO,YAAyD,CAAC,CAC7F,YACA;CACE,SAAS,OAAO;CAChB,OAAO,OAAO,SAAS,OAAO,OAAO,CAAC;AACxC,CACF,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BH,MAAa,OAAO,OAAO,GAAG,UAAU,CAAC,CAAC,WACxC,SACA,MACA;CACA,MAAM,EAAE,QAAQ,OAAO,OAAO,eAC5B,OAAO,IAAI;EACT,WAAWA,WAAuB,SAAS,IAAI;EAC/C,QAAQ,UACN,IAAI,SAAS;GAAE,SAAS;GAAoD;EAAM,CAAC;CACvF,CAAC,GACDC,OACF;CACA,OAAO;AACT,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCD,MAAa,SAAS,SAAiC,SACrD,MAAM,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { App_d_exports } from "./App.mjs";
2
+ export { App_d_exports as App };
@@ -0,0 +1 @@
1
+ export { App_exports as App } from "./App.mjs";
@@ -0,0 +1,20 @@
1
+ import { Effect } from "effect";
2
+ import { defaultAppName } from "@visiolab/effect-firebase/app/App";
3
+ import * as Client from "firebase/app";
4
+ // src/app/internal/app.ts
5
+ /** @internal */
6
+ const initialize = (options, name) => {
7
+ const owned = !Client.getApps().some((app) => app.name === (name ?? defaultAppName));
8
+ return {
9
+ app: Client.initializeApp(options, name),
10
+ owned
11
+ };
12
+ };
13
+ /** @internal */
14
+ const release = ({ app, owned }) => owned ? Effect.tryPromise(() => Client.deleteApp(app)).pipe(Effect.ignore({
15
+ log: "Warn",
16
+ message: `Failed to delete the Firebase client SDK app "${app.name}"`
17
+ })) : Effect.void;
18
+ export { initialize, release };
19
+
20
+ //# sourceMappingURL=app.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.mjs","names":[],"sources":["../../../src/app/internal/app.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { defaultAppName } from \"@visiolab/effect-firebase/app/App\";\nimport * as Client from \"firebase/app\";\nimport type * as App from \"../App.ts\";\n\n/**\n * The app together with whether we are the ones who initialized it.\n *\n * @internal\n */\nexport interface Initialized {\n readonly app: App.App;\n readonly owned: boolean;\n}\n\n/** @internal */\nexport const initialize = (options: Client.FirebaseOptions, name?: string): Initialized => {\n // An app that is already registered under this name was initialized by\n // somebody else, so ending its lifecycle is not ours to do. `initializeApp`\n // still throws when that app was configured differently, so conflicting\n // configuration is not swallowed here.\n const owned = !Client.getApps().some((app) => app.name === (name ?? defaultAppName));\n return { app: Client.initializeApp(options, name), owned };\n};\n\n/** @internal */\nexport const release = ({ app, owned }: Initialized): Effect.Effect<void> =>\n owned\n ? Effect.tryPromise(() => Client.deleteApp(app)).pipe(\n Effect.ignore({\n log: \"Warn\",\n message: `Failed to delete the Firebase client SDK app \"${app.name}\"`,\n }),\n )\n : Effect.void;\n"],"mappings":";;;;;AAgBA,MAAa,cAAc,SAAiC,SAA+B;CAKzF,MAAM,QAAQ,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,QAAQ,IAAI,UAAU,QAAQ,eAAe;CACnF,OAAO;EAAE,KAAK,OAAO,cAAc,SAAS,IAAI;EAAG;CAAM;AAC3D;;AAGA,MAAa,WAAW,EAAE,KAAK,YAC7B,QACI,OAAO,iBAAiB,OAAO,UAAU,GAAG,CAAC,CAAC,CAAC,KAC7C,OAAO,OAAO;CACZ,KAAK;CACL,SAAS,iDAAiD,IAAI,KAAK;AACrE,CAAC,CACH,IACA,OAAO"}
@@ -0,0 +1,106 @@
1
+ import * as DocumentSnapshot from "@visiolab/effect-firebase/firestore/DocumentSnapshot";
2
+ import * as Collection from "@visiolab/effect-firebase/firestore/Collection";
3
+ declare namespace ClientDocumentSnapshot_d_exports {
4
+ export { ClientDocumentSnapshot, Existing, Missing, SnapshotMetadata, existing, make, missing };
5
+ }
6
+ /**
7
+ * What the client SDK reports about where a snapshot came from: the SDK's
8
+ * `SnapshotMetadata`.
9
+ *
10
+ * @see {@link ClientFirestore.ListenOptions} for hearing a change to it on a listen
11
+ *
12
+ * @stability unstable
13
+ * @category models
14
+ * @since 0.1.0
15
+ */
16
+ export interface SnapshotMetadata {
17
+ /**
18
+ * Whether it was served from the local cache instead of confirmed by the
19
+ * server, such as while offline, and so may be out of date.
20
+ */
21
+ readonly fromCache: boolean;
22
+ /**
23
+ * Whether it reflects writes made by this client that the server has not
24
+ * acknowledged yet.
25
+ */
26
+ readonly hasPendingWrites: boolean;
27
+ }
28
+ /**
29
+ * A document that was there when it was read, with the
30
+ * {@link SnapshotMetadata} of that read.
31
+ *
32
+ * @see {@link DocumentSnapshot.Existing} for the portable snapshot it extends
33
+ *
34
+ * @stability unstable
35
+ * @category models
36
+ * @since 0.1.0
37
+ */
38
+ export interface Existing<C extends Collection.Any> extends DocumentSnapshot.Existing<C> {
39
+ readonly metadata: SnapshotMetadata;
40
+ }
41
+ /**
42
+ * A document that was not there when it was read, with the
43
+ * {@link SnapshotMetadata} of that read. Its `fromCache` tells "the cache says
44
+ * it is gone" from "the server says it is gone".
45
+ *
46
+ * @see {@link DocumentSnapshot.Missing} for the portable snapshot it extends
47
+ *
48
+ * @stability unstable
49
+ * @category models
50
+ * @since 0.1.0
51
+ */
52
+ export interface Missing<C extends Collection.Any> extends DocumentSnapshot.Missing<C> {
53
+ readonly metadata: SnapshotMetadata;
54
+ }
55
+ /**
56
+ * A document in `C`, as a read through {@link ClientFirestore.ClientFirestore}
57
+ * found it: {@link Existing} or {@link Missing}.
58
+ *
59
+ * @see {@link DocumentSnapshot.DocumentSnapshot} for the portable snapshot
60
+ *
61
+ * @stability unstable
62
+ * @category models
63
+ * @since 0.1.0
64
+ */
65
+ export type ClientDocumentSnapshot<C extends Collection.Any> = Existing<C> | Missing<C>;
66
+ /**
67
+ * Builds a snapshot of the document at `ref` from what the client SDK's
68
+ * `snapshot.data()` returned and the `snapshot.metadata` it reported.
69
+ *
70
+ * **When to use**
71
+ *
72
+ * Use to turn a snapshot read through the client SDK itself into this
73
+ * library's. An `undefined` `data` builds {@link Missing}, anything else
74
+ * {@link Existing}.
75
+ *
76
+ * @see {@link existing} for a document known to be there
77
+ * @see {@link missing} for a document known not to be there
78
+ *
79
+ * @stability unstable
80
+ * @category constructors
81
+ * @since 0.1.0
82
+ */
83
+ export declare const make: <C extends Collection.Any>(ref: Collection.DocumentReference<C>, data: unknown, metadata: SnapshotMetadata) => ClientDocumentSnapshot<C>;
84
+ /**
85
+ * Builds a snapshot of a document known to be there, such as one a query
86
+ * returned.
87
+ *
88
+ * @see {@link make} for a document that may or may not be there
89
+ *
90
+ * @stability unstable
91
+ * @category constructors
92
+ * @since 0.1.0
93
+ */
94
+ export declare const existing: <C extends Collection.Any>(ref: Collection.DocumentReference<C>, data: unknown, metadata: SnapshotMetadata) => Existing<C>;
95
+ /**
96
+ * Builds a snapshot of a document known not to be there.
97
+ *
98
+ * @see {@link make} for a document that may or may not be there
99
+ *
100
+ * @stability unstable
101
+ * @category constructors
102
+ * @since 0.1.0
103
+ */
104
+ export declare const missing: <C extends Collection.Any>(ref: Collection.DocumentReference<C>, metadata: SnapshotMetadata) => Missing<C>;
105
+ export { ClientDocumentSnapshot_d_exports };
106
+ //# sourceMappingURL=ClientDocumentSnapshot.d.mts.map
@@ -0,0 +1,86 @@
1
+ import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
2
+ import { extraOf } from "./internal/snapshotMetadata.mjs";
3
+ import * as DocumentSnapshot from "@visiolab/effect-firebase/firestore/DocumentSnapshot";
4
+ // src/firestore/ClientDocumentSnapshot.ts
5
+ /**
6
+ * What a read of one document through {@link ClientFirestore.ClientFirestore}
7
+ * returns: a portable {@link DocumentSnapshot.DocumentSnapshot} that also
8
+ * carries the {@link SnapshotMetadata} the client SDK reported for the read.
9
+ *
10
+ * Each variant extends its portable one, so a client snapshot can be handed to
11
+ * portable code as it is, and the portable guards, such as
12
+ * {@link DocumentSnapshot.isExisting}, tell its variants apart.
13
+ *
14
+ * @example Checking whether a read came from the cache
15
+ * ```ts
16
+ * import { Effect, Schema } from "effect";
17
+ * import { Collection, FirestoreModel } from "@visiolab/effect-firebase/firestore";
18
+ * import { ClientFirestore } from "@visiolab/effect-firebase-client/firestore";
19
+ *
20
+ * class User extends FirestoreModel.Class<User>("User")({
21
+ * name: Schema.String,
22
+ * }) {}
23
+ *
24
+ * const Users = Collection.make("users", User);
25
+ *
26
+ * const program = Effect.gen(function* () {
27
+ * const firestore = yield* ClientFirestore.ClientFirestore;
28
+ * const snapshot = yield* firestore.getDoc(Users.doc(Users.id.make("alice")));
29
+ * if (snapshot.metadata.fromCache) {
30
+ * // Served from the local cache, so possibly out of date.
31
+ * }
32
+ * });
33
+ * ```
34
+ *
35
+ * @see {@link ClientQuerySnapshot} for what a read of many documents returns
36
+ *
37
+ * @stability unstable
38
+ * @since 0.1.0
39
+ */
40
+ var ClientDocumentSnapshot_exports = /* @__PURE__ */ __exportAll({
41
+ existing: () => existing,
42
+ make: () => make,
43
+ missing: () => missing
44
+ });
45
+ /**
46
+ * Builds a snapshot of the document at `ref` from what the client SDK's
47
+ * `snapshot.data()` returned and the `snapshot.metadata` it reported.
48
+ *
49
+ * **When to use**
50
+ *
51
+ * Use to turn a snapshot read through the client SDK itself into this
52
+ * library's. An `undefined` `data` builds {@link Missing}, anything else
53
+ * {@link Existing}.
54
+ *
55
+ * @see {@link existing} for a document known to be there
56
+ * @see {@link missing} for a document known not to be there
57
+ *
58
+ * @stability unstable
59
+ * @category constructors
60
+ * @since 0.1.0
61
+ */
62
+ const make = (ref, data, metadata) => DocumentSnapshot.make(ref, data, extraOf(metadata));
63
+ /**
64
+ * Builds a snapshot of a document known to be there, such as one a query
65
+ * returned.
66
+ *
67
+ * @see {@link make} for a document that may or may not be there
68
+ *
69
+ * @stability unstable
70
+ * @category constructors
71
+ * @since 0.1.0
72
+ */
73
+ const existing = (ref, data, metadata) => DocumentSnapshot.existing(ref, data, extraOf(metadata));
74
+ /**
75
+ * Builds a snapshot of a document known not to be there.
76
+ *
77
+ * @see {@link make} for a document that may or may not be there
78
+ *
79
+ * @stability unstable
80
+ * @category constructors
81
+ * @since 0.1.0
82
+ */
83
+ const missing = (ref, metadata) => DocumentSnapshot.missing(ref, extraOf(metadata));
84
+ export { ClientDocumentSnapshot_exports, existing, make, missing };
85
+
86
+ //# sourceMappingURL=ClientDocumentSnapshot.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientDocumentSnapshot.mjs","names":["snapshotMetadata.extraOf"],"sources":["../../src/firestore/ClientDocumentSnapshot.ts"],"sourcesContent":["/**\n * What a read of one document through {@link ClientFirestore.ClientFirestore}\n * returns: a portable {@link DocumentSnapshot.DocumentSnapshot} that also\n * carries the {@link SnapshotMetadata} the client SDK reported for the read.\n *\n * Each variant extends its portable one, so a client snapshot can be handed to\n * portable code as it is, and the portable guards, such as\n * {@link DocumentSnapshot.isExisting}, tell its variants apart.\n *\n * @example Checking whether a read came from the cache\n * ```ts\n * import { Effect, Schema } from \"effect\";\n * import { Collection, FirestoreModel } from \"@visiolab/effect-firebase/firestore\";\n * import { ClientFirestore } from \"@visiolab/effect-firebase-client/firestore\";\n *\n * class User extends FirestoreModel.Class<User>(\"User\")({\n * name: Schema.String,\n * }) {}\n *\n * const Users = Collection.make(\"users\", User);\n *\n * const program = Effect.gen(function* () {\n * const firestore = yield* ClientFirestore.ClientFirestore;\n * const snapshot = yield* firestore.getDoc(Users.doc(Users.id.make(\"alice\")));\n * if (snapshot.metadata.fromCache) {\n * // Served from the local cache, so possibly out of date.\n * }\n * });\n * ```\n *\n * @see {@link ClientQuerySnapshot} for what a read of many documents returns\n *\n * @stability unstable\n * @since 0.1.0\n */\nimport * as DocumentSnapshot from \"@visiolab/effect-firebase/firestore/DocumentSnapshot\";\nimport type * as Collection from \"@visiolab/effect-firebase/firestore/Collection\";\nimport * as snapshotMetadata from \"./internal/snapshotMetadata.ts\";\n\n/**\n * What the client SDK reports about where a snapshot came from: the SDK's\n * `SnapshotMetadata`.\n *\n * @see {@link ClientFirestore.ListenOptions} for hearing a change to it on a listen\n *\n * @stability unstable\n * @category models\n * @since 0.1.0\n */\nexport interface SnapshotMetadata {\n /**\n * Whether it was served from the local cache instead of confirmed by the\n * server, such as while offline, and so may be out of date.\n */\n readonly fromCache: boolean;\n /**\n * Whether it reflects writes made by this client that the server has not\n * acknowledged yet.\n */\n readonly hasPendingWrites: boolean;\n}\n\n/**\n * A document that was there when it was read, with the\n * {@link SnapshotMetadata} of that read.\n *\n * @see {@link DocumentSnapshot.Existing} for the portable snapshot it extends\n *\n * @stability unstable\n * @category models\n * @since 0.1.0\n */\nexport interface Existing<C extends Collection.Any> extends DocumentSnapshot.Existing<C> {\n readonly metadata: SnapshotMetadata;\n}\n\n/**\n * A document that was not there when it was read, with the\n * {@link SnapshotMetadata} of that read. Its `fromCache` tells \"the cache says\n * it is gone\" from \"the server says it is gone\".\n *\n * @see {@link DocumentSnapshot.Missing} for the portable snapshot it extends\n *\n * @stability unstable\n * @category models\n * @since 0.1.0\n */\nexport interface Missing<C extends Collection.Any> extends DocumentSnapshot.Missing<C> {\n readonly metadata: SnapshotMetadata;\n}\n\n/**\n * A document in `C`, as a read through {@link ClientFirestore.ClientFirestore}\n * found it: {@link Existing} or {@link Missing}.\n *\n * @see {@link DocumentSnapshot.DocumentSnapshot} for the portable snapshot\n *\n * @stability unstable\n * @category models\n * @since 0.1.0\n */\nexport type ClientDocumentSnapshot<C extends Collection.Any> = Existing<C> | Missing<C>;\n\n/**\n * Builds a snapshot of the document at `ref` from what the client SDK's\n * `snapshot.data()` returned and the `snapshot.metadata` it reported.\n *\n * **When to use**\n *\n * Use to turn a snapshot read through the client SDK itself into this\n * library's. An `undefined` `data` builds {@link Missing}, anything else\n * {@link Existing}.\n *\n * @see {@link existing} for a document known to be there\n * @see {@link missing} for a document known not to be there\n *\n * @stability unstable\n * @category constructors\n * @since 0.1.0\n */\nexport const make = <C extends Collection.Any>(\n ref: Collection.DocumentReference<C>,\n data: unknown,\n metadata: SnapshotMetadata,\n): ClientDocumentSnapshot<C> =>\n DocumentSnapshot.make(ref, data, snapshotMetadata.extraOf(metadata));\n\n/**\n * Builds a snapshot of a document known to be there, such as one a query\n * returned.\n *\n * @see {@link make} for a document that may or may not be there\n *\n * @stability unstable\n * @category constructors\n * @since 0.1.0\n */\nexport const existing = <C extends Collection.Any>(\n ref: Collection.DocumentReference<C>,\n data: unknown,\n metadata: SnapshotMetadata,\n): Existing<C> => DocumentSnapshot.existing(ref, data, snapshotMetadata.extraOf(metadata));\n\n/**\n * Builds a snapshot of a document known not to be there.\n *\n * @see {@link make} for a document that may or may not be there\n *\n * @stability unstable\n * @category constructors\n * @since 0.1.0\n */\nexport const missing = <C extends Collection.Any>(\n ref: Collection.DocumentReference<C>,\n metadata: SnapshotMetadata,\n): Missing<C> => DocumentSnapshot.missing(ref, snapshotMetadata.extraOf(metadata));\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA,MAAa,QACX,KACA,MACA,aAEA,iBAAiB,KAAK,KAAK,MAAMA,QAAyB,QAAQ,CAAC;;;;;;;;;;;AAYrE,MAAa,YACX,KACA,MACA,aACgB,iBAAiB,SAAS,KAAK,MAAMA,QAAyB,QAAQ,CAAC;;;;;;;;;;AAWzF,MAAa,WACX,KACA,aACe,iBAAiB,QAAQ,KAAKA,QAAyB,QAAQ,CAAC"}