@mirafive/convex 0.0.0-stage → 2.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cloo 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,97 @@
1
- # Temporary Holding Version
1
+ # @mirafive/convex
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
+ MIRA FIVE for [Convex](https://convex.dev): track events and revenue from mutations. A mutation
4
+ cannot use the network, so the event is scheduled in the same transaction and an internal action
5
+ delivers it right after the commit. A mutation that rolls back sends nothing, so an order that
6
+ never happened is never counted. Built on [`@mirafive/node`](https://github.com/mirafive/sdk-node);
7
+ no dependency on `convex`, and it runs in Convex's default runtime (no `"use node"`).
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm install @mirafive/convex
13
+ npx convex env set MIRAFIVE_SECRET_KEY mira_sk_…
14
+ ```
15
+
16
+ ## Setup
17
+
18
+ ```ts
19
+ // convex/mira.ts
20
+ import { MiraConvex } from "@mirafive/convex";
21
+ import { v } from "convex/values";
22
+
23
+ import { internal } from "./_generated/api";
24
+ import { internalAction } from "./_generated/server";
25
+
26
+ // The `: MiraConvex` annotation is required: it breaks the type cycle through `internal`.
27
+ export const mira: MiraConvex = new MiraConvex(internal.mira.deliver);
28
+
29
+ export const deliver = internalAction({
30
+ args: { events: v.array(v.any()) },
31
+ handler: (_ctx, { events }) => mira.deliver(events),
32
+ });
33
+ ```
34
+
35
+ ## Use
36
+
37
+ ```ts
38
+ // convex/orders.ts
39
+ import { v } from "convex/values";
40
+
41
+ import { mutation } from "./_generated/server";
42
+ import { mira } from "./mira";
43
+
44
+ export const pay = mutation({
45
+ args: { orderId: v.id("orders") },
46
+ handler: async (ctx, { orderId }) => {
47
+ const order = await ctx.db.get(orderId);
48
+ await ctx.db.patch(orderId, { status: "paid" });
49
+ await mira.revenue(ctx, {
50
+ userId: order.userId,
51
+ amount: order.totalCents,
52
+ currency: "EUR",
53
+ entryId: `order:${orderId}`,
54
+ // A stable key: a retried mutation schedules the event again, the ingest counts it once.
55
+ dedupeKey: `order:${orderId}:paid`,
56
+ });
57
+ },
58
+ });
59
+ ```
60
+
61
+ | Method | Sends |
62
+ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
63
+ | `mira.track(ctx, { event, userId?, properties?, … })` | A custom event |
64
+ | `mira.identify(ctx, { userId, traits?, externalIds? })` | Who the user is |
65
+ | `mira.group(ctx, { groupId, traits? })` | The company or account |
66
+ | `mira.revenue(ctx, { amount, currency, entryId?, subscription?, … })` | Money for the revenue ledger |
67
+ | `mira.touchpoint(ctx, { kind, source \| channel, userId \| anonymousId, … })` | A touchpoint that is not a visit |
68
+ | `mira.schedule(ctx, events)` | Several at once (`{ method: "track", … }`) |
69
+ | `mira.deliver(events)` | Sends now; for the internal action. Returns `{ sent, failed, errors }`, never throws. |
70
+
71
+ Every method takes the same fields as [`@mirafive/node`](https://github.com/mirafive/sdk-node#readme)
72
+ plus `dedupeKey`. `Date` values are converted for the scheduler. Scheduling never fails your
73
+ mutation: a problem goes to `onError` (`new MiraConvex(ref, { onError })`).
74
+
75
+ ## For AI coding assistants
76
+
77
+ Rules for integrating MIRA FIVE correctly. They hold for every MIRA FIVE SDK.
78
+
79
+ - **Keys:** the public key (`mira_pk_…`) goes in browser and app code. The secret key (`mira_sk_…`)
80
+ goes only into the server's environment (`MIRAFIVE_SECRET_KEY`), never into client code, a
81
+ `NEXT_PUBLIC_`/`VITE_`/`PUBLIC_` variable or a repository. The SDKs refuse the wrong key.
82
+ - **Money** is sent only from the server: integer minor units plus an ISO 4217 currency
83
+ (`amount: 1999, currency: "EUR"` is 19.99 EUR), never floats.
84
+ - **Count once:** give money an `entryId` from the payment provider (`stripe:in_123`), so the
85
+ Stripe connector and retries do not double it. Give business events a stable id:
86
+ `eventId: await eventIdFor("order:123:paid")`. The same key gives the same id in every SDK.
87
+ - **Personal data** never goes into event names or properties. Use your own user id (not an email)
88
+ for `identify`; put email, name and phone in its traits, which MIRA FIVE encrypts at rest.
89
+ - **Consent:** keep `consent: "auto"`; it follows the site's consent banner (Usercentrics,
90
+ Cookiebot, consentmanager, CCM19, Borlabs, any TCF 2.2 CMP, Google Consent Mode). Call
91
+ `consent()` only for a custom banner. Do not gate the SDK behind consent yourself: without
92
+ consent it is cookieless and still counts.
93
+ - **Never block on analytics:** event methods return nothing, never throw, and batch on their
94
+ own. Do not `await` or `try` them. Call `flush()`/`shutdown()` only at the end of a script or a
95
+ serverless function.
96
+ - **Server events and visitors:** pass the browser's `mira.anonymousId` to your server and set it
97
+ as `anonymousId` on server events, so a purchase joins the visit and its source.
@@ -0,0 +1,83 @@
1
+ /**
2
+ * `@mirafive/convex`: MIRA FIVE events from Convex mutations and actions.
3
+ *
4
+ * Mutations are transactional and cannot use the network, so an event is scheduled with
5
+ * `ctx.scheduler` in the same transaction and delivered by an internal action right after it
6
+ * commits. A mutation that rolls back sends nothing, so an order that never happened is never
7
+ * counted. No dependency on `convex`; it runs in Convex's default runtime (no `"use node"`).
8
+ *
9
+ * ```ts
10
+ * // convex/mira.ts
11
+ * import { MiraConvex } from "@mirafive/convex";
12
+ * import { v } from "convex/values";
13
+ * import { internal } from "./_generated/api";
14
+ * import { internalAction } from "./_generated/server";
15
+ *
16
+ * // The `: MiraConvex` annotation is required: it breaks the type cycle through `internal`.
17
+ * export const mira: MiraConvex = new MiraConvex(internal.mira.deliver);
18
+ *
19
+ * export const deliver = internalAction({
20
+ * args: { events: v.array(v.any()) },
21
+ * handler: (_ctx, { events }) => mira.deliver(events),
22
+ * });
23
+ *
24
+ * // convex/orders.ts, in a mutation
25
+ * await mira.revenue(ctx, { userId, amount: 4900, currency: "EUR", dedupeKey: `order:${id}:paid` });
26
+ * ```
27
+ */
28
+ import { type EventMap, type GroupInput, type IdentifyInput, type MiraOptions, type RevenueInput, type TouchpointInput, type TrackInput } from "@mirafive/node";
29
+ export { eventIdFor, MiraError } from "@mirafive/node";
30
+ export type { EventMap, GroupInput, IdentifyInput, MiraOptions, RevenueInput, TouchpointInput, TrackInput, } from "@mirafive/node";
31
+ /** A stable key (`order:123:paid`) that becomes the event id, so a retried mutation counts once. */
32
+ interface Dedupe {
33
+ dedupeKey?: string;
34
+ }
35
+ /** One event as it travels through `ctx.scheduler`: the method, its input and a dedupe key. */
36
+ export type MiraEvent = ({
37
+ method: "track";
38
+ } & TrackInput & Dedupe) | ({
39
+ method: "identify";
40
+ } & IdentifyInput & Dedupe) | ({
41
+ method: "group";
42
+ } & GroupInput & Dedupe) | ({
43
+ method: "revenue";
44
+ } & RevenueInput & Dedupe) | ({
45
+ method: "touchpoint";
46
+ } & TouchpointInput & Dedupe);
47
+ /** The part of a Convex mutation or action context this package uses. */
48
+ export interface SchedulerCtx {
49
+ scheduler: {
50
+ runAfter: (delayMs: number, fn: never, args: never) => Promise<unknown>;
51
+ };
52
+ }
53
+ export interface DeliverResult {
54
+ sent: number;
55
+ failed: number;
56
+ errors: string[];
57
+ }
58
+ export declare class MiraConvex<Events extends EventMap = EventMap> {
59
+ /**
60
+ * @param deliverFunction The internal action that calls `mira.deliver(events)`, for example
61
+ * `internal.mira.deliver`.
62
+ * @param options Delivery options. The key defaults to the deployment's `MIRAFIVE_SECRET_KEY`
63
+ * (`npx convex env set MIRAFIVE_SECRET_KEY mira_sk_…`) and the host to `MIRAFIVE_HOST`.
64
+ */
65
+ private readonly deliverFunction;
66
+ private readonly options;
67
+ constructor(deliverFunction: unknown, options?: MiraOptions);
68
+ /** A custom event, sent after the current mutation commits. */
69
+ track<Name extends keyof Events & string>(ctx: SchedulerCtx, input: TrackInput<Events, Name> & Dedupe): Promise<void>;
70
+ identify(ctx: SchedulerCtx, input: IdentifyInput & Dedupe): Promise<void>;
71
+ group(ctx: SchedulerCtx, input: GroupInput & Dedupe): Promise<void>;
72
+ /** Money for the revenue ledger. Give it a `dedupeKey` or `entryId`, so a retry counts once. */
73
+ revenue(ctx: SchedulerCtx, input: RevenueInput & Dedupe): Promise<void>;
74
+ touchpoint(ctx: SchedulerCtx, input: TouchpointInput & Dedupe): Promise<void>;
75
+ /** Several events in one scheduled delivery. */
76
+ schedule(ctx: SchedulerCtx, events: MiraEvent[]): Promise<void>;
77
+ /**
78
+ * Sends events now and waits for delivery. The internal action's handler calls it; never call
79
+ * it from a mutation or query (they cannot use the network). Never throws: a MIRA FIVE outage
80
+ * must not fail your action. Problems are in `errors`.
81
+ */
82
+ deliver(events: MiraEvent[]): Promise<DeliverResult>;
83
+ }
package/dist/index.js ADDED
@@ -0,0 +1,98 @@
1
+ // src/index.ts
2
+ import {
3
+ eventIdFor,
4
+ Mira,
5
+ MiraError
6
+ } from "@mirafive/node";
7
+ import { eventIdFor as eventIdFor2, MiraError as MiraError2 } from "@mirafive/node";
8
+ var toConvexValue = (event) => JSON.parse(JSON.stringify(event));
9
+
10
+ class MiraConvex {
11
+ deliverFunction;
12
+ options;
13
+ constructor(deliverFunction, options = {}) {
14
+ this.deliverFunction = deliverFunction;
15
+ this.options = options;
16
+ }
17
+ track(ctx, input) {
18
+ return this.schedule(ctx, [{ method: "track", ...input }]);
19
+ }
20
+ identify(ctx, input) {
21
+ return this.schedule(ctx, [{ method: "identify", ...input }]);
22
+ }
23
+ group(ctx, input) {
24
+ return this.schedule(ctx, [{ method: "group", ...input }]);
25
+ }
26
+ revenue(ctx, input) {
27
+ return this.schedule(ctx, [{ method: "revenue", ...input }]);
28
+ }
29
+ touchpoint(ctx, input) {
30
+ return this.schedule(ctx, [{ method: "touchpoint", ...input }]);
31
+ }
32
+ async schedule(ctx, events) {
33
+ if (!events.length)
34
+ return;
35
+ try {
36
+ await ctx.scheduler.runAfter(0, this.deliverFunction, {
37
+ events: events.map(toConvexValue)
38
+ });
39
+ } catch (error) {
40
+ this.options.onError?.(new MiraError("dropped", "could not schedule delivery", { cause: error }));
41
+ }
42
+ }
43
+ async deliver(events) {
44
+ const errors = [];
45
+ const failedIds = new Set;
46
+ let invalid = 0;
47
+ const mira = new Mira({
48
+ maxRetries: 3,
49
+ ...this.options,
50
+ flushAt: 100,
51
+ onError: (error) => {
52
+ errors.push(error.message);
53
+ for (const id of error.eventIds)
54
+ failedIds.add(id);
55
+ this.options.onError?.(error);
56
+ }
57
+ });
58
+ if (errors.length)
59
+ return { sent: 0, failed: events.length, errors };
60
+ for (const item of events) {
61
+ const before = errors.length;
62
+ const eventId = item.eventId ?? (item.dedupeKey ? await eventIdFor(item.dedupeKey) : undefined);
63
+ const { method, dedupeKey: _, ...input } = item;
64
+ switch (method) {
65
+ case "track":
66
+ mira.track({ ...input, eventId });
67
+ break;
68
+ case "identify":
69
+ mira.identify({ ...input, eventId });
70
+ break;
71
+ case "group":
72
+ mira.group({ ...input, eventId });
73
+ break;
74
+ case "revenue":
75
+ mira.revenue({ ...input, eventId });
76
+ break;
77
+ case "touchpoint":
78
+ mira.touchpoint({ ...input, eventId });
79
+ break;
80
+ default:
81
+ errors.push(`MIRA FIVE: unknown method: ${String(method)}`);
82
+ }
83
+ if (errors.length > before)
84
+ invalid += 1;
85
+ }
86
+ await mira.shutdown();
87
+ const failed = invalid + failedIds.size;
88
+ return { sent: Math.max(0, events.length - failed), failed, errors };
89
+ }
90
+ }
91
+ export {
92
+ MiraConvex,
93
+ MiraError2 as MiraError,
94
+ eventIdFor2 as eventIdFor
95
+ };
96
+
97
+ //# debugId=21BF33B329BC4D5064756E2164756E21
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * `@mirafive/convex`: MIRA FIVE events from Convex mutations and actions.\n *\n * Mutations are transactional and cannot use the network, so an event is scheduled with\n * `ctx.scheduler` in the same transaction and delivered by an internal action right after it\n * commits. A mutation that rolls back sends nothing, so an order that never happened is never\n * counted. No dependency on `convex`; it runs in Convex's default runtime (no `\"use node\"`).\n *\n * ```ts\n * // convex/mira.ts\n * import { MiraConvex } from \"@mirafive/convex\";\n * import { v } from \"convex/values\";\n * import { internal } from \"./_generated/api\";\n * import { internalAction } from \"./_generated/server\";\n *\n * // The `: MiraConvex` annotation is required: it breaks the type cycle through `internal`.\n * export const mira: MiraConvex = new MiraConvex(internal.mira.deliver);\n *\n * export const deliver = internalAction({\n * args: { events: v.array(v.any()) },\n * handler: (_ctx, { events }) => mira.deliver(events),\n * });\n *\n * // convex/orders.ts, in a mutation\n * await mira.revenue(ctx, { userId, amount: 4900, currency: \"EUR\", dedupeKey: `order:${id}:paid` });\n * ```\n */\nimport {\n eventIdFor,\n Mira,\n MiraError,\n type EventMap,\n type GroupInput,\n type IdentifyInput,\n type MiraOptions,\n type RevenueInput,\n type TouchpointInput,\n type TrackInput,\n} from \"@mirafive/node\";\n\nexport { eventIdFor, MiraError } from \"@mirafive/node\";\nexport type {\n EventMap,\n GroupInput,\n IdentifyInput,\n MiraOptions,\n RevenueInput,\n TouchpointInput,\n TrackInput,\n} from \"@mirafive/node\";\n\n/** A stable key (`order:123:paid`) that becomes the event id, so a retried mutation counts once. */\ninterface Dedupe {\n dedupeKey?: string;\n}\n\n/** One event as it travels through `ctx.scheduler`: the method, its input and a dedupe key. */\nexport type MiraEvent =\n | ({ method: \"track\" } & TrackInput & Dedupe)\n | ({ method: \"identify\" } & IdentifyInput & Dedupe)\n | ({ method: \"group\" } & GroupInput & Dedupe)\n | ({ method: \"revenue\" } & RevenueInput & Dedupe)\n | ({ method: \"touchpoint\" } & TouchpointInput & Dedupe);\n\n/** The part of a Convex mutation or action context this package uses. */\nexport interface SchedulerCtx {\n scheduler: { runAfter: (delayMs: number, fn: never, args: never) => Promise<unknown> };\n}\n\nexport interface DeliverResult {\n sent: number;\n failed: number;\n errors: string[];\n}\n\n/**\n * Makes an event a Convex value: `Date`s become ISO strings and `undefined` fields disappear,\n * so `ctx.scheduler` accepts it.\n */\nconst toConvexValue = (event: MiraEvent): MiraEvent =>\n JSON.parse(JSON.stringify(event)) as MiraEvent;\n\nexport class MiraConvex<Events extends EventMap = EventMap> {\n /**\n * @param deliverFunction The internal action that calls `mira.deliver(events)`, for example\n * `internal.mira.deliver`.\n * @param options Delivery options. The key defaults to the deployment's `MIRAFIVE_SECRET_KEY`\n * (`npx convex env set MIRAFIVE_SECRET_KEY mira_sk_…`) and the host to `MIRAFIVE_HOST`.\n */\n private readonly deliverFunction: unknown;\n private readonly options: MiraOptions;\n\n constructor(deliverFunction: unknown, options: MiraOptions = {}) {\n this.deliverFunction = deliverFunction;\n this.options = options;\n }\n\n /** A custom event, sent after the current mutation commits. */\n track<Name extends keyof Events & string>(\n ctx: SchedulerCtx,\n input: TrackInput<Events, Name> & Dedupe,\n ): Promise<void> {\n return this.schedule(ctx, [{ method: \"track\", ...(input as TrackInput & Dedupe) }]);\n }\n\n identify(ctx: SchedulerCtx, input: IdentifyInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"identify\", ...input }]);\n }\n\n group(ctx: SchedulerCtx, input: GroupInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"group\", ...input }]);\n }\n\n /** Money for the revenue ledger. Give it a `dedupeKey` or `entryId`, so a retry counts once. */\n revenue(ctx: SchedulerCtx, input: RevenueInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"revenue\", ...input }]);\n }\n\n touchpoint(ctx: SchedulerCtx, input: TouchpointInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"touchpoint\", ...input }]);\n }\n\n /** Several events in one scheduled delivery. */\n async schedule(ctx: SchedulerCtx, events: MiraEvent[]): Promise<void> {\n if (!events.length) return;\n try {\n await ctx.scheduler.runAfter(\n 0,\n this.deliverFunction as never,\n {\n events: events.map(toConvexValue),\n } as never,\n );\n } catch (error) {\n // Analytics must never fail the mutation that records the real fact.\n this.options.onError?.(\n new MiraError(\"dropped\", \"could not schedule delivery\", { cause: error }),\n );\n }\n }\n\n /**\n * Sends events now and waits for delivery. The internal action's handler calls it; never call\n * it from a mutation or query (they cannot use the network). Never throws: a MIRA FIVE outage\n * must not fail your action. Problems are in `errors`.\n */\n async deliver(events: MiraEvent[]): Promise<DeliverResult> {\n const errors: string[] = [];\n const failedIds = new Set<string>();\n let invalid = 0;\n\n const mira = new Mira({\n // Actions have a time limit; fewer retries keep them short.\n maxRetries: 3,\n ...this.options,\n flushAt: 100,\n onError: (error: MiraError) => {\n errors.push(error.message);\n for (const id of error.eventIds) failedIds.add(id);\n this.options.onError?.(error);\n },\n });\n if (errors.length) return { sent: 0, failed: events.length, errors };\n\n for (const item of events) {\n const before = errors.length;\n const eventId =\n item.eventId ?? (item.dedupeKey ? await eventIdFor(item.dedupeKey) : undefined);\n const { method, dedupeKey: _, ...input } = item as MiraEvent & { method: unknown };\n switch (method) {\n case \"track\":\n mira.track({ ...(input as TrackInput), eventId });\n break;\n case \"identify\":\n mira.identify({ ...(input as IdentifyInput), eventId });\n break;\n case \"group\":\n mira.group({ ...(input as GroupInput), eventId });\n break;\n case \"revenue\":\n mira.revenue({ ...(input as RevenueInput), eventId });\n break;\n case \"touchpoint\":\n mira.touchpoint({ ...(input as TouchpointInput), eventId });\n break;\n default:\n errors.push(`MIRA FIVE: unknown method: ${String(method)}`);\n }\n if (errors.length > before) invalid += 1;\n }\n\n await mira.shutdown();\n const failed = invalid + failedIds.size;\n return { sent: Math.max(0, events.length - failed), failed, errors };\n }\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "21BF33B329BC4D5064756E2164756E21",
9
+ "names": []
10
+ }
package/package.json CHANGED
@@ -1,6 +1,62 @@
1
1
  {
2
2
  "name": "@mirafive/convex",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "2.0.0",
4
+ "description": "MIRA FIVE for Convex: track events and revenue from mutations; they are delivered by an internal action only after the transaction commits. No dependency on convex.",
5
+ "keywords": [
6
+ "analytics",
7
+ "attribution",
8
+ "convex",
9
+ "mira-five",
10
+ "mirafive",
11
+ "revenue"
12
+ ],
13
+ "homepage": "https://github.com/mirafive/sdk-convex#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/mirafive/sdk-convex/issues"
16
+ },
17
+ "license": "MIT",
18
+ "author": "Cloo GmbH <hallo@mirafive.io> (https://mirafive.io)",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/mirafive/sdk-convex.git"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "type": "module",
27
+ "sideEffects": false,
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "provenance": true
40
+ },
41
+ "scripts": {
42
+ "build": "bun run build.ts",
43
+ "check": "bun run format:check && bun run lint && bun run typecheck && bun run test && bun run build",
44
+ "format": "oxfmt",
45
+ "format:check": "oxfmt --check",
46
+ "lint": "oxlint",
47
+ "test": "bun test",
48
+ "typecheck": "bun check"
49
+ },
50
+ "dependencies": {
51
+ "@mirafive/node": "^2.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@mirafive/protocol": "^2.0.0",
55
+ "@types/bun": "^1.4.4",
56
+ "oxfmt": "^0.77.0",
57
+ "oxlint": "^1.92.0",
58
+ "oxlint-tsgolint": "^7.0.2006",
59
+ "typescript": "^7.0.2"
60
+ },
61
+ "packageManager": "bun@1.4.4"
62
+ }