@visiolab/effect-firebase 0.0.0-stage → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +81 -2
- package/dist/_virtual/_rolldown/runtime.mjs +12 -0
- package/dist/app/App.d.mts +27 -0
- package/dist/app/App.mjs +27 -0
- package/dist/app/index.d.mts +2 -0
- package/dist/app/index.mjs +1 -0
- package/dist/firestore/Collection.d.mts +423 -0
- package/dist/firestore/Collection.mjs +133 -0
- package/dist/firestore/CollectionGroup.d.mts +164 -0
- package/dist/firestore/CollectionGroup.mjs +84 -0
- package/dist/firestore/DocumentPath.d.mts +95 -0
- package/dist/firestore/DocumentPath.mjs +71 -0
- package/dist/firestore/DocumentSnapshot.d.mts +239 -0
- package/dist/firestore/DocumentSnapshot.mjs +134 -0
- package/dist/firestore/FieldValue.d.mts +332 -0
- package/dist/firestore/FieldValue.mjs +256 -0
- package/dist/firestore/Firestore.d.mts +1165 -0
- package/dist/firestore/Firestore.mjs +274 -0
- package/dist/firestore/FirestoreModel.d.mts +1232 -0
- package/dist/firestore/FirestoreModel.mjs +586 -0
- package/dist/firestore/FirestoreSchema.d.mts +567 -0
- package/dist/firestore/FirestoreSchema.mjs +419 -0
- package/dist/firestore/FirestoreValue.d.mts +145 -0
- package/dist/firestore/FirestoreValue.mjs +87 -0
- package/dist/firestore/GeoPoint.d.mts +90 -0
- package/dist/firestore/GeoPoint.mjs +75 -0
- package/dist/firestore/Patch.d.mts +73 -0
- package/dist/firestore/Patch.mjs +57 -0
- package/dist/firestore/QuerySnapshot.d.mts +107 -0
- package/dist/firestore/QuerySnapshot.mjs +43 -0
- package/dist/firestore/Timestamp.d.mts +273 -0
- package/dist/firestore/Timestamp.mjs +255 -0
- package/dist/firestore/index.d.mts +14 -0
- package/dist/firestore/index.mjs +14 -0
- package/dist/firestore/internal/collection.mjs +156 -0
- package/dist/firestore/internal/collectionGroup.mjs +64 -0
- package/dist/firestore/internal/documentPath.d.mts +4 -0
- package/dist/firestore/internal/documentPath.mjs +42 -0
- package/dist/firestore/internal/documentSnapshot.mjs +63 -0
- package/dist/firestore/internal/fieldValue.d.mts +11 -0
- package/dist/firestore/internal/fieldValue.mjs +88 -0
- package/dist/firestore/internal/firestore.mjs +145 -0
- package/dist/firestore/internal/firestoreError.d.mts +29 -0
- package/dist/firestore/internal/firestoreError.mjs +30 -0
- package/dist/firestore/internal/firestoreModel.mjs +719 -0
- package/dist/firestore/internal/firestoreSchema.mjs +123 -0
- package/dist/firestore/internal/firestoreValue.mjs +108 -0
- package/dist/firestore/internal/firestoreValueWalk.d.mts +58 -0
- package/dist/firestore/internal/firestoreValueWalk.mjs +223 -0
- package/dist/firestore/internal/geoPoint.d.mts +4 -0
- package/dist/firestore/internal/geoPoint.mjs +39 -0
- package/dist/firestore/internal/patch.mjs +19 -0
- package/dist/firestore/internal/querySnapshot.mjs +24 -0
- package/dist/firestore/internal/schemaAST.mjs +35 -0
- package/dist/firestore/internal/snapshotExtra.mjs +35 -0
- package/dist/firestore/internal/streamFromListener.mjs +12 -0
- package/dist/firestore/internal/timestamp.d.mts +4 -0
- package/dist/firestore/internal/timestamp.mjs +66 -0
- package/dist/firestore/internal/timestampSchema.mjs +31 -0
- package/dist/firestore/internal/transactionFromCallback.mjs +66 -0
- package/dist/functions/Callable.d.mts +654 -0
- package/dist/functions/Callable.mjs +450 -0
- package/dist/functions/CallableError.d.mts +297 -0
- package/dist/functions/CallableError.mjs +256 -0
- package/dist/functions/CallableMiddleware.d.mts +213 -0
- package/dist/functions/CallableMiddleware.mjs +52 -0
- package/dist/functions/CallableRequest.d.mts +166 -0
- package/dist/functions/CallableRequest.mjs +18 -0
- package/dist/functions/Caller.d.mts +103 -0
- package/dist/functions/Caller.mjs +115 -0
- package/dist/functions/DocumentTrigger.d.mts +795 -0
- package/dist/functions/DocumentTrigger.mjs +566 -0
- package/dist/functions/FirebaseFunction.d.mts +79 -0
- package/dist/functions/FirebaseFunction.mjs +4 -0
- package/dist/functions/FunctionGroup.d.mts +175 -0
- package/dist/functions/FunctionGroup.mjs +64 -0
- package/dist/functions/index.d.mts +9 -0
- package/dist/functions/index.mjs +9 -0
- package/dist/functions/internal/callable.mjs +167 -0
- package/dist/functions/internal/callableMiddleware.d.mts +19 -0
- package/dist/functions/internal/callableMiddleware.mjs +15 -0
- package/dist/functions/internal/callableRequest.mjs +6 -0
- package/dist/functions/internal/documentTrigger.d.mts +10 -0
- package/dist/functions/internal/documentTrigger.mjs +73 -0
- package/dist/functions/internal/firebaseFunction.d.mts +5 -0
- package/dist/functions/internal/firebaseFunction.mjs +24 -0
- package/dist/functions/internal/functionGroup.mjs +36 -0
- package/package.json +72 -3
- package/src/app/App.ts +24 -0
- package/src/app/index.ts +7 -0
- package/src/firestore/Collection.ts +520 -0
- package/src/firestore/CollectionGroup.ts +245 -0
- package/src/firestore/DocumentPath.ts +114 -0
- package/src/firestore/DocumentSnapshot.ts +308 -0
- package/src/firestore/FieldValue.ts +375 -0
- package/src/firestore/Firestore.ts +1432 -0
- package/src/firestore/FirestoreModel.ts +1884 -0
- package/src/firestore/FirestoreSchema.ts +643 -0
- package/src/firestore/FirestoreValue.ts +207 -0
- package/src/firestore/GeoPoint.ts +105 -0
- package/src/firestore/Patch.ts +117 -0
- package/src/firestore/QuerySnapshot.ts +150 -0
- package/src/firestore/Timestamp.ts +302 -0
- package/src/firestore/index.ts +67 -0
- package/src/firestore/internal/collection.ts +246 -0
- package/src/firestore/internal/collectionGroup.ts +81 -0
- package/src/firestore/internal/documentPath.ts +53 -0
- package/src/firestore/internal/documentSnapshot.ts +117 -0
- package/src/firestore/internal/fieldValue.ts +119 -0
- package/src/firestore/internal/firestore.ts +322 -0
- package/src/firestore/internal/firestoreError.ts +36 -0
- package/src/firestore/internal/firestoreModel.ts +1242 -0
- package/src/firestore/internal/firestoreSchema.ts +218 -0
- package/src/firestore/internal/firestoreValue.ts +202 -0
- package/src/firestore/internal/firestoreValueWalk.ts +349 -0
- package/src/firestore/internal/geoPoint.ts +59 -0
- package/src/firestore/internal/patch.ts +21 -0
- package/src/firestore/internal/querySnapshot.ts +39 -0
- package/src/firestore/internal/schemaAST.ts +83 -0
- package/src/firestore/internal/snapshotExtra.ts +47 -0
- package/src/firestore/internal/streamFromListener.ts +27 -0
- package/src/firestore/internal/timestamp.ts +119 -0
- package/src/firestore/internal/timestampSchema.ts +42 -0
- package/src/firestore/internal/transactionFromCallback.ts +106 -0
- package/src/functions/Callable.ts +855 -0
- package/src/functions/CallableError.ts +348 -0
- package/src/functions/CallableMiddleware.ts +279 -0
- package/src/functions/CallableRequest.ts +207 -0
- package/src/functions/Caller.ts +141 -0
- package/src/functions/DocumentTrigger.ts +927 -0
- package/src/functions/FirebaseFunction.ts +96 -0
- package/src/functions/FunctionGroup.ts +225 -0
- package/src/functions/index.ts +62 -0
- package/src/functions/internal/callable.ts +272 -0
- package/src/functions/internal/callableMiddleware.ts +54 -0
- package/src/functions/internal/callableRequest.ts +8 -0
- package/src/functions/internal/documentTrigger.ts +143 -0
- package/src/functions/internal/firebaseFunction.ts +58 -0
- package/src/functions/internal/functionGroup.ts +47 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Cause, Effect, Queue, Result, Stream } from "effect";
|
|
2
|
+
// src/firestore/internal/streamFromListener.ts
|
|
3
|
+
/** @internal */
|
|
4
|
+
const streamFromListener = (options) => Stream.callback((queue) => Effect.acquireRelease(Effect.sync(() => options.subscribe((snapshot) => {
|
|
5
|
+
const element = options.map(snapshot);
|
|
6
|
+
if (Result.isSuccess(element)) Queue.offerUnsafe(queue, element.success);
|
|
7
|
+
else Queue.failCauseUnsafe(queue, Cause.fail(element.failure));
|
|
8
|
+
}, (error) => Queue.failCauseUnsafe(queue, Cause.fail(options.onError(error))))), (unsubscribe) => Effect.sync(unsubscribe)), {
|
|
9
|
+
bufferSize: 1,
|
|
10
|
+
strategy: "sliding"
|
|
11
|
+
});
|
|
12
|
+
export { streamFromListener };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { DateTime, Effect, Equal, Hash, Inspectable, Option, Order, Predicate } from "effect";
|
|
2
|
+
// src/firestore/internal/timestamp.ts
|
|
3
|
+
/** @internal */
|
|
4
|
+
const TypeId = "~@visiolab/effect-firebase/firestore/Timestamp";
|
|
5
|
+
/** `0001-01-01T00:00:00Z`, the earliest instant Firestore addresses. */
|
|
6
|
+
const minSeconds = -62135596800;
|
|
7
|
+
/** `9999-12-31T23:59:59Z`, the latest. */
|
|
8
|
+
const maxSeconds = 253402300799;
|
|
9
|
+
const maxNanoseconds = 999999999;
|
|
10
|
+
const nanosecondsPerMillisecond = 1e6;
|
|
11
|
+
/** Kept apart from the guards below, which narrow a `number` to `never`. */
|
|
12
|
+
const inSecondsRange = (n) => Number.isInteger(n) && n >= minSeconds && n <= maxSeconds;
|
|
13
|
+
const inNanosecondsRange = (n) => Number.isInteger(n) && n >= 0 && n <= maxNanoseconds;
|
|
14
|
+
/** @internal */
|
|
15
|
+
const isTimestamp = (u) => Predicate.hasProperty(u, "~@visiolab/effect-firebase/firestore/Timestamp") && u["~@visiolab/effect-firebase/firestore/Timestamp"] === "~@visiolab/effect-firebase/firestore/Timestamp" && Predicate.hasProperty(u, "seconds") && Predicate.hasProperty(u, "nanoseconds") && Predicate.isNumber(u.seconds) && Predicate.isNumber(u.nanoseconds) && inSecondsRange(u.seconds) && inNanosecondsRange(u.nanoseconds);
|
|
16
|
+
const Proto = {
|
|
17
|
+
...Inspectable.BaseProto,
|
|
18
|
+
[TypeId]: TypeId,
|
|
19
|
+
toJSON() {
|
|
20
|
+
return {
|
|
21
|
+
_id: "Timestamp",
|
|
22
|
+
seconds: this.seconds,
|
|
23
|
+
nanoseconds: this.nanoseconds
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
[Equal.symbol](that) {
|
|
27
|
+
return isTimestamp(that) && this.seconds === that.seconds && this.nanoseconds === that.nanoseconds;
|
|
28
|
+
},
|
|
29
|
+
[Hash.symbol]() {
|
|
30
|
+
return Hash.combine(Hash.number(this.seconds), Hash.number(this.nanoseconds));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const makeUnchecked = (seconds, nanoseconds) => Object.assign(Object.create(Proto), {
|
|
34
|
+
seconds,
|
|
35
|
+
nanoseconds
|
|
36
|
+
});
|
|
37
|
+
/** @internal */
|
|
38
|
+
const makeUnsafe = (seconds, nanoseconds) => {
|
|
39
|
+
if (!inSecondsRange(seconds)) throw new Error(`Invalid Firestore timestamp: seconds must be an integer between ${minSeconds} and ${maxSeconds}, got ${seconds}`);
|
|
40
|
+
if (!inNanosecondsRange(nanoseconds)) throw new Error(`Invalid Firestore timestamp: nanoseconds must be an integer between 0 and ${maxNanoseconds}, got ${nanoseconds}`);
|
|
41
|
+
return makeUnchecked(seconds, nanoseconds);
|
|
42
|
+
};
|
|
43
|
+
/** @internal */
|
|
44
|
+
const make = (seconds, nanoseconds) => inSecondsRange(seconds) && inNanosecondsRange(nanoseconds) ? Option.some(makeUnchecked(seconds, nanoseconds)) : Option.none();
|
|
45
|
+
/** Splits milliseconds into the second and the fraction of it Firestore stores. */
|
|
46
|
+
const partsOfMillis = (millis) => {
|
|
47
|
+
const seconds = Math.floor(millis / 1e3);
|
|
48
|
+
return [seconds, Math.floor((millis - seconds * 1e3) * nanosecondsPerMillisecond)];
|
|
49
|
+
};
|
|
50
|
+
/** @internal */
|
|
51
|
+
const fromMillisUnsafe = (millis) => makeUnsafe(...partsOfMillis(millis));
|
|
52
|
+
/** @internal */
|
|
53
|
+
const fromMillis = (millis) => make(...partsOfMillis(millis));
|
|
54
|
+
/** @internal */
|
|
55
|
+
const fromDateTimeUnsafe = (dateTime) => fromMillisUnsafe(DateTime.toEpochMillis(dateTime));
|
|
56
|
+
/** @internal */
|
|
57
|
+
const fromDateTime = (dateTime) => fromMillis(DateTime.toEpochMillis(dateTime));
|
|
58
|
+
/** @internal */
|
|
59
|
+
const now = Effect.map(DateTime.now, fromDateTimeUnsafe);
|
|
60
|
+
/** @internal */
|
|
61
|
+
const toMillis = (self) => self.seconds * 1e3 + Math.floor(self.nanoseconds / nanosecondsPerMillisecond);
|
|
62
|
+
/** @internal */
|
|
63
|
+
const toDateTime = (self) => DateTime.makeUnsafe(toMillis(self));
|
|
64
|
+
/** @internal */
|
|
65
|
+
const Order$1 = Order.make((self, that) => self.seconds === that.seconds ? Order.Number(self.nanoseconds, that.nanoseconds) : Order.Number(self.seconds, that.seconds));
|
|
66
|
+
export { Order$1 as Order, TypeId, fromDateTime, fromDateTimeUnsafe, fromMillis, fromMillisUnsafe, isTimestamp, make, makeUnsafe, now, toDateTime, toMillis };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isTimestamp, make } from "./timestamp.mjs";
|
|
2
|
+
import { Effect, Equal, Schema, SchemaGetter, SchemaIssue } from "effect";
|
|
3
|
+
// src/firestore/internal/timestampSchema.ts
|
|
4
|
+
/**
|
|
5
|
+
* Apart from the other Firestore schemas, so that deriving `toCodecFirestore`,
|
|
6
|
+
* which writes instants as timestamps, need not import the schemas that
|
|
7
|
+
* derive it in turn.
|
|
8
|
+
*/
|
|
9
|
+
/** Writes a timestamp as JSON without losing the digits finer than a millisecond. */
|
|
10
|
+
const TimestampJson = Schema.Struct({
|
|
11
|
+
seconds: Schema.Int,
|
|
12
|
+
nanoseconds: Schema.Int
|
|
13
|
+
});
|
|
14
|
+
/** @internal */
|
|
15
|
+
const Timestamp = Schema.declare(isTimestamp, {
|
|
16
|
+
representation: {
|
|
17
|
+
id: "@visiolab/effect-firebase/firestore/Timestamp",
|
|
18
|
+
payload: null
|
|
19
|
+
},
|
|
20
|
+
expected: "a Firestore Timestamp",
|
|
21
|
+
toEquivalence: () => Equal.equals,
|
|
22
|
+
toCodecFirestore: () => void 0,
|
|
23
|
+
toCodecJson: () => Schema.link()(TimestampJson, {
|
|
24
|
+
decode: SchemaGetter.transformEffect((json, options) => Effect.fromOption(make(json.seconds, json.nanoseconds)).pipe(Effect.mapError(() => new SchemaIssue.InvalidValue({ message: "Expected an instant Firestore can store" }, json, options)))),
|
|
25
|
+
encode: SchemaGetter.transform((value) => ({
|
|
26
|
+
seconds: value.seconds,
|
|
27
|
+
nanoseconds: value.nanoseconds
|
|
28
|
+
}))
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
export { Timestamp };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { FirestoreError } from "./firestoreError.mjs";
|
|
2
|
+
import { Cause, Effect, Exit, Option } from "effect";
|
|
3
|
+
import { constVoid } from "effect/Function";
|
|
4
|
+
// src/firestore/internal/transactionFromCallback.ts
|
|
5
|
+
/**
|
|
6
|
+
* What the callback throws when the body fails with anything but a
|
|
7
|
+
* `FirestoreError` that carries its backend's cause.
|
|
8
|
+
*
|
|
9
|
+
* It carries no `code` on purpose: an SDK decides whether to retry by the code
|
|
10
|
+
* of what it caught, and a body's own error that happens to carry one would
|
|
11
|
+
* otherwise be retried as if Firestore had raised it.
|
|
12
|
+
*/
|
|
13
|
+
var BodyFailed = class {
|
|
14
|
+
cause;
|
|
15
|
+
constructor(cause) {
|
|
16
|
+
this.cause = cause;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* What the callback throws for a body that failed with `cause`.
|
|
21
|
+
*
|
|
22
|
+
* A `FirestoreError` goes back as the SDK's own error behind it, so the SDK
|
|
23
|
+
* decides by its own rules whether to retry it - a read answered with ABORTED
|
|
24
|
+
* under contention, or an outage that passes - rather than by a copy of them
|
|
25
|
+
* kept here. Anything else goes back as {@link BodyFailed}, which it never
|
|
26
|
+
* retries.
|
|
27
|
+
*/
|
|
28
|
+
const thrownFor = (cause) => {
|
|
29
|
+
const error = Option.getOrUndefined(Cause.findErrorOption(cause));
|
|
30
|
+
return error instanceof FirestoreError && error.cause !== void 0 ? error.cause : new BodyFailed(cause);
|
|
31
|
+
};
|
|
32
|
+
/** @internal */
|
|
33
|
+
const transactionFromCallback = (options) => ({
|
|
34
|
+
run: (body, hookOptions) => runOver(options, body, hookOptions),
|
|
35
|
+
context: options.context
|
|
36
|
+
});
|
|
37
|
+
/** Runs `body` in a transaction through `options.run`, once per attempt. */
|
|
38
|
+
const runOver = (options, body, hookOptions) => Effect.uninterruptibleMask((restore) => {
|
|
39
|
+
const controller = new AbortController();
|
|
40
|
+
let failure;
|
|
41
|
+
const callback = async (transaction) => {
|
|
42
|
+
const operations = options.operations(transaction);
|
|
43
|
+
const exit = await Effect.runPromiseExit(body(operations), { signal: controller.signal });
|
|
44
|
+
if (Exit.isSuccess(exit)) return exit.value;
|
|
45
|
+
const thrown = thrownFor(exit.cause);
|
|
46
|
+
failure = {
|
|
47
|
+
thrown,
|
|
48
|
+
cause: exit.cause
|
|
49
|
+
};
|
|
50
|
+
throw thrown;
|
|
51
|
+
};
|
|
52
|
+
let running;
|
|
53
|
+
try {
|
|
54
|
+
running = options.run(callback, hookOptions);
|
|
55
|
+
} catch (cause) {
|
|
56
|
+
running = Promise.reject(cause);
|
|
57
|
+
}
|
|
58
|
+
return restore(Effect.tryPromise({
|
|
59
|
+
try: () => running,
|
|
60
|
+
catch: (cause) => failure !== void 0 && cause === failure.thrown ? new BodyFailed(failure.cause) : options.onError(cause)
|
|
61
|
+
})).pipe(Effect.onInterrupt(() => {
|
|
62
|
+
controller.abort();
|
|
63
|
+
return Effect.promise(() => running.then(constVoid, constVoid));
|
|
64
|
+
}), Effect.catchIf((error) => error instanceof BodyFailed, (failed) => Effect.failCause(failed.cause)));
|
|
65
|
+
});
|
|
66
|
+
export { transactionFromCallback };
|