@visiolab/effect-firebase-client 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.
- package/LICENSE +21 -0
- package/README.md +70 -2
- package/dist/_virtual/_rolldown/runtime.mjs +12 -0
- package/dist/app/App.d.mts +117 -0
- package/dist/app/App.mjs +149 -0
- package/dist/app/App.mjs.map +1 -0
- package/dist/app/index.d.mts +2 -0
- package/dist/app/index.mjs +1 -0
- package/dist/app/internal/app.mjs +20 -0
- package/dist/app/internal/app.mjs.map +1 -0
- package/dist/firestore/ClientDocumentSnapshot.d.mts +106 -0
- package/dist/firestore/ClientDocumentSnapshot.mjs +86 -0
- package/dist/firestore/ClientDocumentSnapshot.mjs.map +1 -0
- package/dist/firestore/ClientFirestore.d.mts +331 -0
- package/dist/firestore/ClientFirestore.mjs +146 -0
- package/dist/firestore/ClientFirestore.mjs.map +1 -0
- package/dist/firestore/ClientFirestoreValue.d.mts +61 -0
- package/dist/firestore/ClientFirestoreValue.mjs +62 -0
- package/dist/firestore/ClientFirestoreValue.mjs.map +1 -0
- package/dist/firestore/ClientQuerySnapshot.d.mts +52 -0
- package/dist/firestore/ClientQuerySnapshot.mjs +58 -0
- package/dist/firestore/ClientQuerySnapshot.mjs.map +1 -0
- package/dist/firestore/index.d.mts +5 -0
- package/dist/firestore/index.mjs +5 -0
- package/dist/firestore/internal/firestore.mjs +158 -0
- package/dist/firestore/internal/firestore.mjs.map +1 -0
- package/dist/firestore/internal/firestoreValue.mjs +43 -0
- package/dist/firestore/internal/firestoreValue.mjs.map +1 -0
- package/dist/firestore/internal/snapshotMetadata.mjs +15 -0
- package/dist/firestore/internal/snapshotMetadata.mjs.map +1 -0
- package/dist/functions/CallableClient.d.mts +139 -0
- package/dist/functions/CallableClient.mjs +215 -0
- package/dist/functions/CallableClient.mjs.map +1 -0
- package/dist/functions/ClientFunctions.d.mts +112 -0
- package/dist/functions/ClientFunctions.mjs +105 -0
- package/dist/functions/ClientFunctions.mjs.map +1 -0
- package/dist/functions/index.d.mts +3 -0
- package/dist/functions/index.mjs +3 -0
- package/package.json +63 -3
- package/src/app/App.ts +163 -0
- package/src/app/index.ts +7 -0
- package/src/app/internal/app.ts +35 -0
- package/src/firestore/ClientDocumentSnapshot.ts +156 -0
- package/src/firestore/ClientFirestore.ts +410 -0
- package/src/firestore/ClientFirestoreValue.ts +94 -0
- package/src/firestore/ClientQuerySnapshot.ts +93 -0
- package/src/firestore/index.ts +30 -0
- package/src/firestore/internal/firestore.ts +264 -0
- package/src/firestore/internal/firestoreValue.ts +58 -0
- package/src/firestore/internal/snapshotMetadata.ts +14 -0
- package/src/functions/CallableClient.ts +296 -0
- package/src/functions/ClientFunctions.ts +149 -0
- package/src/functions/index.ts +15 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { ClientFunctions } from "./ClientFunctions.mjs";
|
|
3
|
+
import { Effect, Schema } from "effect";
|
|
4
|
+
import * as Callable from "@visiolab/effect-firebase/functions/Callable";
|
|
5
|
+
import * as CallableError from "@visiolab/effect-firebase/functions/CallableError";
|
|
6
|
+
import * as FunctionGroup from "@visiolab/effect-firebase/functions/FunctionGroup";
|
|
7
|
+
import * as Sdk from "firebase/functions";
|
|
8
|
+
// src/functions/CallableClient.ts
|
|
9
|
+
/**
|
|
10
|
+
* Callable Clients: call the Callables a server serves, with the Payload, the
|
|
11
|
+
* success value and the errors typed by their contract.
|
|
12
|
+
*
|
|
13
|
+
* A client calls through the {@link ClientFunctions.ClientFunctions} in
|
|
14
|
+
* context, so the region and the emulator are set once, where that is
|
|
15
|
+
* provided.
|
|
16
|
+
*
|
|
17
|
+
* @example Calling a Callable
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { Effect, Layer, Schema } from "effect";
|
|
20
|
+
* import { Callable } from "@visiolab/effect-firebase/functions";
|
|
21
|
+
* import { App } from "@visiolab/effect-firebase-client/app";
|
|
22
|
+
* import { CallableClient, ClientFunctions } from "@visiolab/effect-firebase-client/functions";
|
|
23
|
+
*
|
|
24
|
+
* const Greet = Callable.make("greet", {
|
|
25
|
+
* payload: { name: Schema.String },
|
|
26
|
+
* success: Schema.String,
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* const program = Effect.gen(function* () {
|
|
30
|
+
* const { greet } = yield* CallableClient.make(Greet);
|
|
31
|
+
* const message = yield* greet({ name: "Ada" });
|
|
32
|
+
* yield* Effect.log(message);
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* const FunctionsLive = ClientFunctions.layer().pipe(
|
|
36
|
+
* Layer.provide(App.layer({ apiKey: "<api key>", projectId: "my-project", appId: "<app id>" })),
|
|
37
|
+
* );
|
|
38
|
+
*
|
|
39
|
+
* program.pipe(Effect.provide(FunctionsLive));
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @stability unstable
|
|
43
|
+
* @since 0.3.0
|
|
44
|
+
*/
|
|
45
|
+
var CallableClient_exports = /* @__PURE__ */ __exportAll({ make: () => make });
|
|
46
|
+
/** The ` [<status>]` the SDK appends to the message of an error built from an answer. */
|
|
47
|
+
const statusSuffix = / \[(\d+)\]$/;
|
|
48
|
+
/**
|
|
49
|
+
* The messages of the SDK's errors for an answer it can't read: not a JSON
|
|
50
|
+
* object, or one without `data` or `error`.
|
|
51
|
+
*/
|
|
52
|
+
const malformedAnswer = /Response is (?:not valid JSON object|missing data field)\.$/;
|
|
53
|
+
/**
|
|
54
|
+
* The client function of `callable`, served as `deployment`. `errors` are the
|
|
55
|
+
* schemas of every error it can be answered with, its middleware's included.
|
|
56
|
+
*/
|
|
57
|
+
const method = (functions, callable, deployment, errors) => {
|
|
58
|
+
const deployedName = deployment.name;
|
|
59
|
+
const span = {
|
|
60
|
+
kind: "client",
|
|
61
|
+
attributes: deployment.attributes
|
|
62
|
+
};
|
|
63
|
+
const call = Sdk.httpsCallable(functions, deployedName);
|
|
64
|
+
const encode = Schema.encodeUnknownEffect(Schema.toCodecJson(callable.payload));
|
|
65
|
+
const decode = Schema.decodeUnknownEffect(Schema.toCodecJson(callable.success));
|
|
66
|
+
const fail = (reason) => new CallableError.CallableError({
|
|
67
|
+
callable: deployedName,
|
|
68
|
+
reason
|
|
69
|
+
});
|
|
70
|
+
const run = Effect.fn(`CallableClient.${deployedName}`, span)(function* (payload) {
|
|
71
|
+
const data = yield* encode(payload).pipe(Effect.mapError((cause) => fail(new CallableError.EncodeError({ cause }))));
|
|
72
|
+
const result = yield* Effect.tryPromise({
|
|
73
|
+
try: () => call(data),
|
|
74
|
+
catch: (error) => error
|
|
75
|
+
}).pipe(Effect.catch(decodeFailure));
|
|
76
|
+
return yield* decode(result.data).pipe(Effect.mapError((cause) => fail(new CallableError.DecodeError({ cause }))));
|
|
77
|
+
});
|
|
78
|
+
/**
|
|
79
|
+
* Turns what the SDK threw into the declared error it carries, or into a
|
|
80
|
+
* `CallableError`.
|
|
81
|
+
*/
|
|
82
|
+
const decodeFailure = (error) => {
|
|
83
|
+
if (!(error instanceof Sdk.FunctionsError)) return Effect.fail(fail(new CallableError.TransportError({ cause: error })));
|
|
84
|
+
const status = statusSuffix.exec(error.message)?.[1];
|
|
85
|
+
if (status === void 0 || status === "0") {
|
|
86
|
+
if (malformedAnswer.test(error.message)) return Effect.fail(fail(new CallableError.DecodeError({ cause: error })));
|
|
87
|
+
return Effect.fail(fail(new CallableError.TransportError({ cause: error })));
|
|
88
|
+
}
|
|
89
|
+
const code = error.code.replace(/^functions\//, "");
|
|
90
|
+
const candidates = errors.filter((schema) => Callable.getErrorCode(schema) === code);
|
|
91
|
+
if (candidates.length === 0 || error.details === void 0) return Effect.fail(fail(new CallableError.ResponseError({
|
|
92
|
+
code,
|
|
93
|
+
message: error.message.replace(statusSuffix, ""),
|
|
94
|
+
details: error.details
|
|
95
|
+
})));
|
|
96
|
+
return Schema.decodeUnknownEffect(Schema.toCodecJson(Schema.Union(candidates)))(error.details).pipe(Effect.mapError((cause) => fail(new CallableError.DecodeError({ cause }))), Effect.flatMap(Effect.fail));
|
|
97
|
+
};
|
|
98
|
+
return run;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Builds the client of a Callable in no group, or of every Callable member of
|
|
102
|
+
* a Function Group.
|
|
103
|
+
*
|
|
104
|
+
* **When to use**
|
|
105
|
+
*
|
|
106
|
+
* Use to call Callables from the browser or any other client SDK program.
|
|
107
|
+
*
|
|
108
|
+
* **Details**
|
|
109
|
+
*
|
|
110
|
+
* Returns a record keyed by Callable name: `const { greet } = yield*
|
|
111
|
+
* CallableClient.make(Greet)` for a Callable in no group, and
|
|
112
|
+
* `const users = yield* CallableClient.make(Users)` for a group, where
|
|
113
|
+
* `users.create` calls `users-create`. A group's members of other kinds, which
|
|
114
|
+
* no client calls, are left out. The region of the
|
|
115
|
+
* {@link ClientFunctions.ClientFunctions} in context is bound once, here.
|
|
116
|
+
*
|
|
117
|
+
* Build a member's client from its group. A client built from the member on
|
|
118
|
+
* its own calls the name without the group's prefix, which the server doesn't
|
|
119
|
+
* export, and fails with `not-found`. Nothing checks this at runtime.
|
|
120
|
+
*
|
|
121
|
+
* Each call encodes the Payload with `Schema.toCodecJson`, sends it as is
|
|
122
|
+
* through the SDK's `httpsCallable`, and decodes the answer the same way.
|
|
123
|
+
*
|
|
124
|
+
* When the server answers with an error, the client strips the `functions/`
|
|
125
|
+
* prefix from its code and decodes its `details` against the declared errors
|
|
126
|
+
* that carry that code. It fails with the decoded error, so `Effect.catchTag`
|
|
127
|
+
* recovers from it. Every other failure is a
|
|
128
|
+
* {@link CallableError.CallableError}:
|
|
129
|
+
*
|
|
130
|
+
* - `EncodeError` when the Payload doesn't encode. Nothing is sent.
|
|
131
|
+
* - `DecodeError` when the success value doesn't decode, the `details` of
|
|
132
|
+
* an error don't decode against the declared errors with its code, as after
|
|
133
|
+
* the server and the client drift apart, or the answer isn't one the SDK
|
|
134
|
+
* can read: not a JSON object, or one without `data`.
|
|
135
|
+
* - `ResponseError` when the server answers with a code no declared error
|
|
136
|
+
* carries, or without details, as on a defect. `not-found` usually means a
|
|
137
|
+
* wrong region, or a name the server doesn't export, such as a group's
|
|
138
|
+
* member called without its group. A `deadline-exceeded` the server sends
|
|
139
|
+
* is a `ResponseError` too.
|
|
140
|
+
* - `TransportError` when no answer arrived: a network failure, the SDK's
|
|
141
|
+
* own timeout (`deadline-exceeded`), a cancelled call, or a deleted
|
|
142
|
+
* Functions instance. The SDK appends the HTTP status of an answer to its
|
|
143
|
+
* error's message as ` [<status>]`, and status 0 to a network failure. The
|
|
144
|
+
* client treats an error without that suffix, or with status 0, as no
|
|
145
|
+
* answer.
|
|
146
|
+
*
|
|
147
|
+
* Each call runs in a `kind: "client"` span named `CallableClient.<deployed
|
|
148
|
+
* name>`, such as `CallableClient.users-create`, with the attributes
|
|
149
|
+
* `rpc.system: "firebase_callable"`, `rpc.method` (the Callable's name),
|
|
150
|
+
* `rpc.service` (the group, for a member) and `faas.name` (the deployed name).
|
|
151
|
+
* The span isn't linked to the server's span of the same call: the two land in
|
|
152
|
+
* separate traces. It carries no uid; add one with `Effect.annotateCurrentSpan`
|
|
153
|
+
* around the call when you want it.
|
|
154
|
+
*
|
|
155
|
+
* @example Injecting a client as a service
|
|
156
|
+
* ```ts
|
|
157
|
+
* import { Context, Layer, Schema } from "effect";
|
|
158
|
+
* import { Callable } from "@visiolab/effect-firebase/functions";
|
|
159
|
+
* import { CallableClient } from "@visiolab/effect-firebase-client/functions";
|
|
160
|
+
*
|
|
161
|
+
* const Greet = Callable.make("greet", {
|
|
162
|
+
* payload: { name: Schema.String },
|
|
163
|
+
* success: Schema.String,
|
|
164
|
+
* });
|
|
165
|
+
*
|
|
166
|
+
* class GreetClient extends Context.Service<GreetClient, CallableClient.Client<typeof Greet>>()(
|
|
167
|
+
* "app/GreetClient",
|
|
168
|
+
* ) {
|
|
169
|
+
* static readonly layer = Layer.effect(GreetClient, CallableClient.make(Greet));
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @example Calling the members of a group
|
|
174
|
+
* ```ts
|
|
175
|
+
* import { Effect, Schema } from "effect";
|
|
176
|
+
* import { Callable, FunctionGroup } from "@visiolab/effect-firebase/functions";
|
|
177
|
+
* import { CallableClient } from "@visiolab/effect-firebase-client/functions";
|
|
178
|
+
*
|
|
179
|
+
* const CreateUser = Callable.make("create", {
|
|
180
|
+
* payload: { name: Schema.String },
|
|
181
|
+
* success: Schema.String,
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* class Users extends FunctionGroup.make("users").add(CreateUser) {}
|
|
185
|
+
*
|
|
186
|
+
* const program = Effect.gen(function* () {
|
|
187
|
+
* const users = yield* CallableClient.make(Users);
|
|
188
|
+
* // Calls `users-create`.
|
|
189
|
+
* return yield* users.create({ name: "Ada" });
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* @see {@link ClientFunctions.ClientFunctions} for the region and emulator it calls
|
|
194
|
+
* @see {@link Functions.make} for serving a Callable in no group
|
|
195
|
+
* @see {@link Functions.group} for serving the members of a group
|
|
196
|
+
*
|
|
197
|
+
* @stability unstable
|
|
198
|
+
* @category constructors
|
|
199
|
+
* @since 0.3.0
|
|
200
|
+
*/
|
|
201
|
+
const make = (target) => Effect.map(Effect.service(ClientFunctions), ({ instance }) => {
|
|
202
|
+
if (!FunctionGroup.isFunctionGroup(target)) {
|
|
203
|
+
const callable = target;
|
|
204
|
+
return { [callable.name]: method(instance, callable, Callable.deployment(callable), Callable.errorSchemas(callable)) };
|
|
205
|
+
}
|
|
206
|
+
const client = {};
|
|
207
|
+
for (const [name, member] of Object.entries(target.functions)) {
|
|
208
|
+
if (member.kind !== "Callable") continue;
|
|
209
|
+
client[name] = method(instance, member, Callable.deployment(target, name), Callable.errorSchemas(target, name));
|
|
210
|
+
}
|
|
211
|
+
return client;
|
|
212
|
+
});
|
|
213
|
+
export { CallableClient_exports, make };
|
|
214
|
+
|
|
215
|
+
//# sourceMappingURL=CallableClient.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallableClient.mjs","names":["ClientFunctions.ClientFunctions"],"sources":["../../src/functions/CallableClient.ts"],"sourcesContent":["/**\n * Callable Clients: call the Callables a server serves, with the Payload, the\n * success value and the errors typed by their contract.\n *\n * A client calls through the {@link ClientFunctions.ClientFunctions} in\n * context, so the region and the emulator are set once, where that is\n * provided.\n *\n * @example Calling a Callable\n * ```ts\n * import { Effect, Layer, Schema } from \"effect\";\n * import { Callable } from \"@visiolab/effect-firebase/functions\";\n * import { App } from \"@visiolab/effect-firebase-client/app\";\n * import { CallableClient, ClientFunctions } from \"@visiolab/effect-firebase-client/functions\";\n *\n * const Greet = Callable.make(\"greet\", {\n * payload: { name: Schema.String },\n * success: Schema.String,\n * });\n *\n * const program = Effect.gen(function* () {\n * const { greet } = yield* CallableClient.make(Greet);\n * const message = yield* greet({ name: \"Ada\" });\n * yield* Effect.log(message);\n * });\n *\n * const FunctionsLive = ClientFunctions.layer().pipe(\n * Layer.provide(App.layer({ apiKey: \"<api key>\", projectId: \"my-project\", appId: \"<app id>\" })),\n * );\n *\n * program.pipe(Effect.provide(FunctionsLive));\n * ```\n *\n * @stability unstable\n * @since 0.3.0\n */\nimport { Effect, Schema } from \"effect\";\nimport * as Callable from \"@visiolab/effect-firebase/functions/Callable\";\nimport * as CallableError from \"@visiolab/effect-firebase/functions/CallableError\";\nimport * as FunctionGroup from \"@visiolab/effect-firebase/functions/FunctionGroup\";\nimport * as Sdk from \"firebase/functions\";\nimport * as ClientFunctions from \"./ClientFunctions.ts\";\n\n/**\n * A client of one Callable: a function from its Payload to an Effect of its\n * success value, failing with its declared errors or a `CallableError`.\n *\n * @stability unstable\n * @category models\n * @since 0.3.0\n */\nexport type Method<C extends Callable.Any> = (\n payload: Callable.Payload<C>,\n) => Effect.Effect<Callable.Success<C>, Callable.Error<C> | CallableError.CallableError>;\n\n/**\n * What {@link make} returns: one {@link Method} per Callable, keyed by the\n * Callable's name. For a Function Group, one per Callable member.\n *\n * @stability unstable\n * @category models\n * @since 0.3.0\n */\nexport type Client<T extends Callable.Any | FunctionGroup.Any> = {\n readonly [C in Members<T> as C[\"name\"]]: Method<C>;\n};\n\n/**\n * The Callables a client of `T` calls: the Callable members of a Function\n * Group, or the Callable itself. Members of other kinds are left out.\n *\n * @stability unstable\n * @category type-level\n * @since 0.3.0\n */\nexport type Members<T extends Callable.Any | FunctionGroup.Any> = T extends FunctionGroup.Any\n ? FunctionGroup.Members<T, Callable.Any>\n : T;\n\n/** The ` [<status>]` the SDK appends to the message of an error built from an answer. */\nconst statusSuffix = / \\[(\\d+)\\]$/;\n\n/**\n * The messages of the SDK's errors for an answer it can't read: not a JSON\n * object, or one without `data` or `error`.\n */\nconst malformedAnswer = /Response is (?:not valid JSON object|missing data field)\\.$/;\n\n/**\n * The client function of `callable`, served as `deployment`. `errors` are the\n * schemas of every error it can be answered with, its middleware's included.\n */\nconst method = (\n functions: Sdk.Functions,\n callable: Callable.Any,\n deployment: Callable.Deployment,\n errors: ReadonlyArray<Schema.Top>,\n) => {\n const deployedName = deployment.name;\n const span = { kind: \"client\", attributes: deployment.attributes } as const;\n const call = Sdk.httpsCallable(functions, deployedName);\n const encode = Schema.encodeUnknownEffect(\n Schema.toCodecJson(callable.payload as Schema.Codec<unknown>),\n );\n const decode = Schema.decodeUnknownEffect(\n Schema.toCodecJson(callable.success as Schema.Codec<unknown>),\n );\n const fail = (reason: CallableError.Reason) =>\n new CallableError.CallableError({ callable: deployedName, reason });\n const run = Effect.fn(\n `CallableClient.${deployedName}`,\n span,\n )(function* (payload: unknown) {\n const data = yield* encode(payload).pipe(\n Effect.mapError((cause) => fail(new CallableError.EncodeError({ cause }))),\n );\n const result = yield* Effect.tryPromise({\n try: () => call(data),\n catch: (error) => error,\n }).pipe(Effect.catch(decodeFailure));\n return yield* decode(result.data).pipe(\n Effect.mapError((cause) => fail(new CallableError.DecodeError({ cause }))),\n );\n });\n\n /**\n * Turns what the SDK threw into the declared error it carries, or into a\n * `CallableError`.\n */\n const decodeFailure = (error: unknown): Effect.Effect<never, unknown> => {\n if (!(error instanceof Sdk.FunctionsError)) {\n return Effect.fail(fail(new CallableError.TransportError({ cause: error })));\n }\n // The SDK appends the HTTP status to the message of an error built from\n // an answer, and status 0 to a network failure. The errors it makes\n // itself, such as its timeout or a cancellation, carry no status.\n const status = statusSuffix.exec(error.message)?.[1];\n if (status === undefined || status === \"0\") {\n // An answer arrived, but not one the SDK could read.\n if (malformedAnswer.test(error.message)) {\n return Effect.fail(fail(new CallableError.DecodeError({ cause: error })));\n }\n return Effect.fail(fail(new CallableError.TransportError({ cause: error })));\n }\n const code = error.code.replace(/^functions\\//, \"\") as CallableError.ErrorCode;\n const candidates = errors.filter((schema) => Callable.getErrorCode(schema) === code);\n if (candidates.length === 0 || error.details === undefined) {\n return Effect.fail(\n fail(\n new CallableError.ResponseError({\n code,\n message: error.message.replace(statusSuffix, \"\"),\n details: error.details,\n }),\n ),\n );\n }\n return Schema.decodeUnknownEffect(\n Schema.toCodecJson(Schema.Union(candidates) as unknown as Schema.Codec<unknown>),\n )(error.details).pipe(\n Effect.mapError((cause) => fail(new CallableError.DecodeError({ cause }))),\n Effect.flatMap(Effect.fail),\n );\n };\n return run;\n};\n\n/**\n * Builds the client of a Callable in no group, or of every Callable member of\n * a Function Group.\n *\n * **When to use**\n *\n * Use to call Callables from the browser or any other client SDK program.\n *\n * **Details**\n *\n * Returns a record keyed by Callable name: `const { greet } = yield*\n * CallableClient.make(Greet)` for a Callable in no group, and\n * `const users = yield* CallableClient.make(Users)` for a group, where\n * `users.create` calls `users-create`. A group's members of other kinds, which\n * no client calls, are left out. The region of the\n * {@link ClientFunctions.ClientFunctions} in context is bound once, here.\n *\n * Build a member's client from its group. A client built from the member on\n * its own calls the name without the group's prefix, which the server doesn't\n * export, and fails with `not-found`. Nothing checks this at runtime.\n *\n * Each call encodes the Payload with `Schema.toCodecJson`, sends it as is\n * through the SDK's `httpsCallable`, and decodes the answer the same way.\n *\n * When the server answers with an error, the client strips the `functions/`\n * prefix from its code and decodes its `details` against the declared errors\n * that carry that code. It fails with the decoded error, so `Effect.catchTag`\n * recovers from it. Every other failure is a\n * {@link CallableError.CallableError}:\n *\n * - `EncodeError` when the Payload doesn't encode. Nothing is sent.\n * - `DecodeError` when the success value doesn't decode, the `details` of\n * an error don't decode against the declared errors with its code, as after\n * the server and the client drift apart, or the answer isn't one the SDK\n * can read: not a JSON object, or one without `data`.\n * - `ResponseError` when the server answers with a code no declared error\n * carries, or without details, as on a defect. `not-found` usually means a\n * wrong region, or a name the server doesn't export, such as a group's\n * member called without its group. A `deadline-exceeded` the server sends\n * is a `ResponseError` too.\n * - `TransportError` when no answer arrived: a network failure, the SDK's\n * own timeout (`deadline-exceeded`), a cancelled call, or a deleted\n * Functions instance. The SDK appends the HTTP status of an answer to its\n * error's message as ` [<status>]`, and status 0 to a network failure. The\n * client treats an error without that suffix, or with status 0, as no\n * answer.\n *\n * Each call runs in a `kind: \"client\"` span named `CallableClient.<deployed\n * name>`, such as `CallableClient.users-create`, with the attributes\n * `rpc.system: \"firebase_callable\"`, `rpc.method` (the Callable's name),\n * `rpc.service` (the group, for a member) and `faas.name` (the deployed name).\n * The span isn't linked to the server's span of the same call: the two land in\n * separate traces. It carries no uid; add one with `Effect.annotateCurrentSpan`\n * around the call when you want it.\n *\n * @example Injecting a client as a service\n * ```ts\n * import { Context, Layer, Schema } from \"effect\";\n * import { Callable } from \"@visiolab/effect-firebase/functions\";\n * import { CallableClient } from \"@visiolab/effect-firebase-client/functions\";\n *\n * const Greet = Callable.make(\"greet\", {\n * payload: { name: Schema.String },\n * success: Schema.String,\n * });\n *\n * class GreetClient extends Context.Service<GreetClient, CallableClient.Client<typeof Greet>>()(\n * \"app/GreetClient\",\n * ) {\n * static readonly layer = Layer.effect(GreetClient, CallableClient.make(Greet));\n * }\n * ```\n *\n * @example Calling the members of a group\n * ```ts\n * import { Effect, Schema } from \"effect\";\n * import { Callable, FunctionGroup } from \"@visiolab/effect-firebase/functions\";\n * import { CallableClient } from \"@visiolab/effect-firebase-client/functions\";\n *\n * const CreateUser = Callable.make(\"create\", {\n * payload: { name: Schema.String },\n * success: Schema.String,\n * });\n *\n * class Users extends FunctionGroup.make(\"users\").add(CreateUser) {}\n *\n * const program = Effect.gen(function* () {\n * const users = yield* CallableClient.make(Users);\n * // Calls `users-create`.\n * return yield* users.create({ name: \"Ada\" });\n * });\n * ```\n *\n * @see {@link ClientFunctions.ClientFunctions} for the region and emulator it calls\n * @see {@link Functions.make} for serving a Callable in no group\n * @see {@link Functions.group} for serving the members of a group\n *\n * @stability unstable\n * @category constructors\n * @since 0.3.0\n */\nexport const make = <T extends Callable.Any | FunctionGroup.Any>(\n target: T,\n): Effect.Effect<Client<T>, never, ClientFunctions.ClientFunctions> =>\n Effect.map(Effect.service(ClientFunctions.ClientFunctions), ({ instance }) => {\n if (!FunctionGroup.isFunctionGroup(target)) {\n const callable = target as Callable.Any;\n return {\n [callable.name]: method(\n instance,\n callable,\n Callable.deployment(callable),\n Callable.errorSchemas(callable),\n ),\n } as Client<T>;\n }\n const client: Record<string, ReturnType<typeof method>> = {};\n for (const [name, member] of Object.entries(target.functions)) {\n // Only Callables are called by a client.\n if (member.kind !== \"Callable\") continue;\n client[name] = method(\n instance,\n member as Callable.Any,\n Callable.deployment(target, name),\n Callable.errorSchemas(target, name),\n );\n }\n return client as Client<T>;\n });\n"],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { App } from "../app/App.mjs";
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import * as Client from "firebase/functions";
|
|
4
|
+
declare namespace ClientFunctions_d_exports {
|
|
5
|
+
export { ClientFunctions, Emulator, Options, layer, make };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The client SDK's `Functions` instance for one region.
|
|
9
|
+
*
|
|
10
|
+
* @stability unstable
|
|
11
|
+
* @category models
|
|
12
|
+
* @since 0.3.0
|
|
13
|
+
*/
|
|
14
|
+
export interface ClientFunctions {
|
|
15
|
+
/** The SDK's own `Functions` instance, for what this package doesn't wrap. */
|
|
16
|
+
readonly instance: Client.Functions;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Service key for {@link ClientFunctions}.
|
|
20
|
+
*
|
|
21
|
+
* **When to use**
|
|
22
|
+
*
|
|
23
|
+
* Use to give every Callable Client one region and emulator setting. Provide
|
|
24
|
+
* it with {@link layer}. A {@link CallableClient.make} client reads it once,
|
|
25
|
+
* when it is built.
|
|
26
|
+
*
|
|
27
|
+
* @see {@link layer} for providing it
|
|
28
|
+
* @see {@link CallableClient.make} for the clients that call through it
|
|
29
|
+
*
|
|
30
|
+
* @stability unstable
|
|
31
|
+
* @category services
|
|
32
|
+
* @since 0.3.0
|
|
33
|
+
*/
|
|
34
|
+
export declare const ClientFunctions: Context.Service<ClientFunctions, ClientFunctions>;
|
|
35
|
+
/**
|
|
36
|
+
* Where the Functions emulator runs.
|
|
37
|
+
*
|
|
38
|
+
* @stability unstable
|
|
39
|
+
* @category models
|
|
40
|
+
* @since 0.3.0
|
|
41
|
+
*/
|
|
42
|
+
export interface Emulator {
|
|
43
|
+
readonly host: string;
|
|
44
|
+
readonly port: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for {@link make} and {@link layer}.
|
|
48
|
+
*
|
|
49
|
+
* @stability unstable
|
|
50
|
+
* @category models
|
|
51
|
+
* @since 0.3.0
|
|
52
|
+
*/
|
|
53
|
+
export interface Options {
|
|
54
|
+
/**
|
|
55
|
+
* The region the functions are deployed to, such as `europe-west1`, or a
|
|
56
|
+
* custom domain that serves them. Defaults to the SDK's, `us-central1`. A
|
|
57
|
+
* function called in a region it isn't deployed to fails with `not-found`.
|
|
58
|
+
*/
|
|
59
|
+
readonly regionOrCustomDomain?: string | undefined;
|
|
60
|
+
/** Calls the Functions emulator at this address instead of the deployed functions. */
|
|
61
|
+
readonly emulator?: Emulator | undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets the client SDK's `Functions` instance of the {@link App.App} in
|
|
65
|
+
* context, for one region.
|
|
66
|
+
*
|
|
67
|
+
* **When to use**
|
|
68
|
+
*
|
|
69
|
+
* Use to build the service inside an effect of your own. Most programs provide
|
|
70
|
+
* it with {@link layer} instead.
|
|
71
|
+
*
|
|
72
|
+
* **Details**
|
|
73
|
+
*
|
|
74
|
+
* Wraps `getFunctions(app, regionOrCustomDomain)`, and connects the emulator
|
|
75
|
+
* when `emulator` is given. For a second region, build a second service.
|
|
76
|
+
*
|
|
77
|
+
* @see {@link layer} for the same as a layer
|
|
78
|
+
*
|
|
79
|
+
* @stability unstable
|
|
80
|
+
* @category constructors
|
|
81
|
+
* @since 0.3.0
|
|
82
|
+
*/
|
|
83
|
+
export declare const make: (options?: Options) => Effect.Effect<ClientFunctions, never, App>;
|
|
84
|
+
/**
|
|
85
|
+
* A layer that provides {@link ClientFunctions} for the {@link App.App} in
|
|
86
|
+
* context.
|
|
87
|
+
*
|
|
88
|
+
* **When to use**
|
|
89
|
+
*
|
|
90
|
+
* Use to set the region and the emulator once, for every Callable Client built
|
|
91
|
+
* on it.
|
|
92
|
+
*
|
|
93
|
+
* @example Calling the Functions emulator
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { Layer } from "effect";
|
|
96
|
+
* import { App } from "@visiolab/effect-firebase-client/app";
|
|
97
|
+
* import { ClientFunctions } from "@visiolab/effect-firebase-client/functions";
|
|
98
|
+
*
|
|
99
|
+
* const FunctionsLive = ClientFunctions.layer({
|
|
100
|
+
* emulator: { host: "127.0.0.1", port: 5001 },
|
|
101
|
+
* }).pipe(Layer.provide(App.layer({ projectId: "demo-project" })));
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @see {@link make} for what it wraps
|
|
105
|
+
*
|
|
106
|
+
* @stability unstable
|
|
107
|
+
* @category layers
|
|
108
|
+
* @since 0.3.0
|
|
109
|
+
*/
|
|
110
|
+
export declare const layer: (options?: Options) => Layer.Layer<ClientFunctions, never, App>;
|
|
111
|
+
export { ClientFunctions_d_exports };
|
|
112
|
+
//# sourceMappingURL=ClientFunctions.d.mts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { App } from "../app/App.mjs";
|
|
3
|
+
import { Context, Effect, Layer } from "effect";
|
|
4
|
+
import * as Client from "firebase/functions";
|
|
5
|
+
// src/functions/ClientFunctions.ts
|
|
6
|
+
/**
|
|
7
|
+
* Cloud Functions for Firebase on the client SDK: the `Functions` instance
|
|
8
|
+
* that a Callable Client calls through, for one region.
|
|
9
|
+
*
|
|
10
|
+
* A call that fails with `not-found` usually went to the wrong region, or to a
|
|
11
|
+
* name the server doesn't export: build the client of a Function Group's
|
|
12
|
+
* member from its group, so it calls `<group>-<name>`.
|
|
13
|
+
*
|
|
14
|
+
* @example Pointing the client at a region
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { Layer } from "effect";
|
|
17
|
+
* import { App } from "@visiolab/effect-firebase-client/app";
|
|
18
|
+
* import { ClientFunctions } from "@visiolab/effect-firebase-client/functions";
|
|
19
|
+
*
|
|
20
|
+
* const FunctionsLive = ClientFunctions.layer({ regionOrCustomDomain: "europe-west1" }).pipe(
|
|
21
|
+
* Layer.provide(App.layer({ apiKey: "<api key>", projectId: "my-project", appId: "<app id>" })),
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @stability unstable
|
|
26
|
+
* @since 0.3.0
|
|
27
|
+
*/
|
|
28
|
+
var ClientFunctions_exports = /* @__PURE__ */ __exportAll({
|
|
29
|
+
ClientFunctions: () => ClientFunctions,
|
|
30
|
+
layer: () => layer,
|
|
31
|
+
make: () => make
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Service key for {@link ClientFunctions}.
|
|
35
|
+
*
|
|
36
|
+
* **When to use**
|
|
37
|
+
*
|
|
38
|
+
* Use to give every Callable Client one region and emulator setting. Provide
|
|
39
|
+
* it with {@link layer}. A {@link CallableClient.make} client reads it once,
|
|
40
|
+
* when it is built.
|
|
41
|
+
*
|
|
42
|
+
* @see {@link layer} for providing it
|
|
43
|
+
* @see {@link CallableClient.make} for the clients that call through it
|
|
44
|
+
*
|
|
45
|
+
* @stability unstable
|
|
46
|
+
* @category services
|
|
47
|
+
* @since 0.3.0
|
|
48
|
+
*/
|
|
49
|
+
const ClientFunctions = Context.Service("@visiolab/effect-firebase-client/functions/ClientFunctions");
|
|
50
|
+
/**
|
|
51
|
+
* Gets the client SDK's `Functions` instance of the {@link App.App} in
|
|
52
|
+
* context, for one region.
|
|
53
|
+
*
|
|
54
|
+
* **When to use**
|
|
55
|
+
*
|
|
56
|
+
* Use to build the service inside an effect of your own. Most programs provide
|
|
57
|
+
* it with {@link layer} instead.
|
|
58
|
+
*
|
|
59
|
+
* **Details**
|
|
60
|
+
*
|
|
61
|
+
* Wraps `getFunctions(app, regionOrCustomDomain)`, and connects the emulator
|
|
62
|
+
* when `emulator` is given. For a second region, build a second service.
|
|
63
|
+
*
|
|
64
|
+
* @see {@link layer} for the same as a layer
|
|
65
|
+
*
|
|
66
|
+
* @stability unstable
|
|
67
|
+
* @category constructors
|
|
68
|
+
* @since 0.3.0
|
|
69
|
+
*/
|
|
70
|
+
const make = Effect.fn("ClientFunctions.make")(function* (options) {
|
|
71
|
+
const app = yield* App;
|
|
72
|
+
const instance = Client.getFunctions(app, options?.regionOrCustomDomain);
|
|
73
|
+
if (options?.emulator !== void 0) Client.connectFunctionsEmulator(instance, options.emulator.host, options.emulator.port);
|
|
74
|
+
return { instance };
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* A layer that provides {@link ClientFunctions} for the {@link App.App} in
|
|
78
|
+
* context.
|
|
79
|
+
*
|
|
80
|
+
* **When to use**
|
|
81
|
+
*
|
|
82
|
+
* Use to set the region and the emulator once, for every Callable Client built
|
|
83
|
+
* on it.
|
|
84
|
+
*
|
|
85
|
+
* @example Calling the Functions emulator
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { Layer } from "effect";
|
|
88
|
+
* import { App } from "@visiolab/effect-firebase-client/app";
|
|
89
|
+
* import { ClientFunctions } from "@visiolab/effect-firebase-client/functions";
|
|
90
|
+
*
|
|
91
|
+
* const FunctionsLive = ClientFunctions.layer({
|
|
92
|
+
* emulator: { host: "127.0.0.1", port: 5001 },
|
|
93
|
+
* }).pipe(Layer.provide(App.layer({ projectId: "demo-project" })));
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* @see {@link make} for what it wraps
|
|
97
|
+
*
|
|
98
|
+
* @stability unstable
|
|
99
|
+
* @category layers
|
|
100
|
+
* @since 0.3.0
|
|
101
|
+
*/
|
|
102
|
+
const layer = (options) => Layer.effect(ClientFunctions, make(options));
|
|
103
|
+
export { ClientFunctions, ClientFunctions_exports, layer, make };
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=ClientFunctions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientFunctions.mjs","names":["App.App"],"sources":["../../src/functions/ClientFunctions.ts"],"sourcesContent":["/**\n * Cloud Functions for Firebase on the client SDK: the `Functions` instance\n * that a Callable Client calls through, for one region.\n *\n * A call that fails with `not-found` usually went to the wrong region, or to a\n * name the server doesn't export: build the client of a Function Group's\n * member from its group, so it calls `<group>-<name>`.\n *\n * @example Pointing the client at a region\n * ```ts\n * import { Layer } from \"effect\";\n * import { App } from \"@visiolab/effect-firebase-client/app\";\n * import { ClientFunctions } from \"@visiolab/effect-firebase-client/functions\";\n *\n * const FunctionsLive = ClientFunctions.layer({ regionOrCustomDomain: \"europe-west1\" }).pipe(\n * Layer.provide(App.layer({ apiKey: \"<api key>\", projectId: \"my-project\", appId: \"<app id>\" })),\n * );\n * ```\n *\n * @stability unstable\n * @since 0.3.0\n */\nimport { Context, Effect, Layer } from \"effect\";\nimport * as Client from \"firebase/functions\";\nimport * as App from \"../app/App.ts\";\n// Only the documentation links to it.\n// oxlint-disable-next-line no-unused-vars\nimport type * as CallableClient from \"./CallableClient.ts\";\n\n/**\n * The client SDK's `Functions` instance for one region.\n *\n * @stability unstable\n * @category models\n * @since 0.3.0\n */\nexport interface ClientFunctions {\n /** The SDK's own `Functions` instance, for what this package doesn't wrap. */\n readonly instance: Client.Functions;\n}\n\n/**\n * Service key for {@link ClientFunctions}.\n *\n * **When to use**\n *\n * Use to give every Callable Client one region and emulator setting. Provide\n * it with {@link layer}. A {@link CallableClient.make} client reads it once,\n * when it is built.\n *\n * @see {@link layer} for providing it\n * @see {@link CallableClient.make} for the clients that call through it\n *\n * @stability unstable\n * @category services\n * @since 0.3.0\n */\nexport const ClientFunctions = Context.Service<ClientFunctions>(\n \"@visiolab/effect-firebase-client/functions/ClientFunctions\",\n);\n\n/**\n * Where the Functions emulator runs.\n *\n * @stability unstable\n * @category models\n * @since 0.3.0\n */\nexport interface Emulator {\n readonly host: string;\n readonly port: number;\n}\n\n/**\n * Options for {@link make} and {@link layer}.\n *\n * @stability unstable\n * @category models\n * @since 0.3.0\n */\nexport interface Options {\n /**\n * The region the functions are deployed to, such as `europe-west1`, or a\n * custom domain that serves them. Defaults to the SDK's, `us-central1`. A\n * function called in a region it isn't deployed to fails with `not-found`.\n */\n readonly regionOrCustomDomain?: string | undefined;\n /** Calls the Functions emulator at this address instead of the deployed functions. */\n readonly emulator?: Emulator | undefined;\n}\n\n/**\n * Gets the client SDK's `Functions` instance of the {@link App.App} in\n * context, for one region.\n *\n * **When to use**\n *\n * Use to build the service inside an effect of your own. Most programs provide\n * it with {@link layer} instead.\n *\n * **Details**\n *\n * Wraps `getFunctions(app, regionOrCustomDomain)`, and connects the emulator\n * when `emulator` is given. For a second region, build a second service.\n *\n * @see {@link layer} for the same as a layer\n *\n * @stability unstable\n * @category constructors\n * @since 0.3.0\n */\nexport const make: (options?: Options) => Effect.Effect<ClientFunctions, never, App.App> =\n Effect.fn(\"ClientFunctions.make\")(function* (options?: Options) {\n const app = yield* App.App;\n const instance = Client.getFunctions(app, options?.regionOrCustomDomain);\n if (options?.emulator !== undefined) {\n Client.connectFunctionsEmulator(instance, options.emulator.host, options.emulator.port);\n }\n return { instance };\n });\n\n/**\n * A layer that provides {@link ClientFunctions} for the {@link App.App} in\n * context.\n *\n * **When to use**\n *\n * Use to set the region and the emulator once, for every Callable Client built\n * on it.\n *\n * @example Calling the Functions emulator\n * ```ts\n * import { Layer } from \"effect\";\n * import { App } from \"@visiolab/effect-firebase-client/app\";\n * import { ClientFunctions } from \"@visiolab/effect-firebase-client/functions\";\n *\n * const FunctionsLive = ClientFunctions.layer({\n * emulator: { host: \"127.0.0.1\", port: 5001 },\n * }).pipe(Layer.provide(App.layer({ projectId: \"demo-project\" })));\n * ```\n *\n * @see {@link make} for what it wraps\n *\n * @stability unstable\n * @category layers\n * @since 0.3.0\n */\nexport const layer = (options?: Options): Layer.Layer<ClientFunctions, never, App.App> =>\n Layer.effect(ClientFunctions, make(options));\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,MAAa,kBAAkB,QAAQ,QACrC,4DACF;;;;;;;;;;;;;;;;;;;;;AAoDA,MAAa,OACX,OAAO,GAAG,sBAAsB,CAAC,CAAC,WAAW,SAAmB;CAC9D,MAAM,MAAM,OAAOA;CACnB,MAAM,WAAW,OAAO,aAAa,KAAK,SAAS,oBAAoB;CACvE,IAAI,SAAS,aAAa,KAAA,GACxB,OAAO,yBAAyB,UAAU,QAAQ,SAAS,MAAM,QAAQ,SAAS,IAAI;CAExF,OAAO,EAAE,SAAS;AACpB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BH,MAAa,SAAS,YACpB,MAAM,OAAO,iBAAiB,KAAK,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,66 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visiolab/effect-firebase-client",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Firebase client SDK implementation of the @visiolab/effect-firebase services.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"effect",
|
|
7
|
+
"firebase",
|
|
8
|
+
"typescript"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/VisioLab/effect-firebase",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/VisioLab/effect-firebase/issues"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/VisioLab/effect-firebase.git",
|
|
18
|
+
"directory": "packages/client"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"src/**/*.ts",
|
|
22
|
+
"dist/**/*.mjs",
|
|
23
|
+
"dist/**/*.mjs.map",
|
|
24
|
+
"dist/**/*.d.mts",
|
|
25
|
+
"dist/**/*.d.mts.map"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"sideEffects": [],
|
|
29
|
+
"exports": {
|
|
30
|
+
"./app": "./dist/app/index.mjs",
|
|
31
|
+
"./app/App": "./dist/app/App.mjs",
|
|
32
|
+
"./firestore": "./dist/firestore/index.mjs",
|
|
33
|
+
"./firestore/ClientDocumentSnapshot": "./dist/firestore/ClientDocumentSnapshot.mjs",
|
|
34
|
+
"./firestore/ClientFirestore": "./dist/firestore/ClientFirestore.mjs",
|
|
35
|
+
"./firestore/ClientFirestoreValue": "./dist/firestore/ClientFirestoreValue.mjs",
|
|
36
|
+
"./firestore/ClientQuerySnapshot": "./dist/firestore/ClientQuerySnapshot.mjs",
|
|
37
|
+
"./functions": "./dist/functions/index.mjs",
|
|
38
|
+
"./functions/CallableClient": "./dist/functions/CallableClient.mjs",
|
|
39
|
+
"./functions/ClientFunctions": "./dist/functions/ClientFunctions.mjs",
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@effect/vitest": "^4.1.0",
|
|
47
|
+
"effect": "4.1.0",
|
|
48
|
+
"firebase": "^13.0.0",
|
|
49
|
+
"typescript": "^7.0.2",
|
|
50
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
|
|
51
|
+
"vite-plus": "1.4.0",
|
|
52
|
+
"vitest": "5.0.5",
|
|
53
|
+
"@visiolab/effect-firebase": "^0.3.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"effect": "~4.1.0",
|
|
57
|
+
"firebase": "^13.0.0",
|
|
58
|
+
"@visiolab/effect-firebase": "^0.3.0"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "vp pack",
|
|
62
|
+
"dev": "vp pack --watch",
|
|
63
|
+
"test": "vp test",
|
|
64
|
+
"check": "vp check"
|
|
65
|
+
}
|
|
6
66
|
}
|