@soulcraft/sdk 2.0.0 → 2.0.2
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/dist/client/index.d.ts +5 -38
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -47
- package/dist/client/index.js.map +1 -1
- package/dist/client/namespace-proxy.d.ts +3 -4
- package/dist/client/namespace-proxy.d.ts.map +1 -1
- package/dist/client/namespace-proxy.js +3 -4
- package/dist/client/namespace-proxy.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/modules/hall/browser.d.ts +83 -27
- package/dist/modules/hall/browser.d.ts.map +1 -1
- package/dist/modules/hall/browser.js +238 -49
- package/dist/modules/hall/browser.js.map +1 -1
- package/dist/modules/hall/media.d.ts +164 -0
- package/dist/modules/hall/media.d.ts.map +1 -0
- package/dist/modules/hall/media.js +182 -0
- package/dist/modules/hall/media.js.map +1 -0
- package/dist/modules/hall/server.d.ts +83 -6
- package/dist/modules/hall/server.d.ts.map +1 -1
- package/dist/modules/hall/server.js +206 -9
- package/dist/modules/hall/server.js.map +1 -1
- package/dist/modules/hall/types.d.ts +548 -25
- package/dist/modules/hall/types.d.ts.map +1 -1
- package/dist/modules/hall/types.js +12 -7
- package/dist/modules/hall/types.js.map +1 -1
- package/dist/server/hall-handlers.d.ts +40 -12
- package/dist/server/hall-handlers.d.ts.map +1 -1
- package/dist/server/hall-handlers.js +40 -12
- package/dist/server/hall-handlers.js.map +1 -1
- package/dist/server/handlers/chat/engine.d.ts.map +1 -1
- package/dist/server/handlers/chat/engine.js +5 -1
- package/dist/server/handlers/chat/engine.js.map +1 -1
- package/dist/server/handlers/chat/types.d.ts +17 -2
- package/dist/server/handlers/chat/types.d.ts.map +1 -1
- package/dist/server/hono-router.d.ts +2 -9
- package/dist/server/hono-router.d.ts.map +1 -1
- package/dist/server/hono-router.js +2 -46
- package/dist/server/hono-router.js.map +1 -1
- package/dist/server/index.d.ts +4 -19
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +10 -29
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts +2 -41
- package/dist/types.d.ts.map +1 -1
- package/docs/ADR-005-hall-integration.md +449 -0
- package/package.json +1 -1
- package/dist/client/create-client-sdk.d.ts +0 -113
- package/dist/client/create-client-sdk.d.ts.map +0 -1
- package/dist/client/create-client-sdk.js +0 -169
- package/dist/client/create-client-sdk.js.map +0 -1
- package/dist/modules/app-context/index.d.ts +0 -214
- package/dist/modules/app-context/index.d.ts.map +0 -1
- package/dist/modules/app-context/index.js +0 -569
- package/dist/modules/app-context/index.js.map +0 -1
- package/dist/modules/billing/firestore-provider.d.ts +0 -60
- package/dist/modules/billing/firestore-provider.d.ts.map +0 -1
- package/dist/modules/billing/firestore-provider.js +0 -315
- package/dist/modules/billing/firestore-provider.js.map +0 -1
- package/dist/modules/brainy/proxy.d.ts +0 -48
- package/dist/modules/brainy/proxy.d.ts.map +0 -1
- package/dist/modules/brainy/proxy.js +0 -95
- package/dist/modules/brainy/proxy.js.map +0 -1
- package/dist/server/create-sdk.d.ts +0 -74
- package/dist/server/create-sdk.d.ts.map +0 -1
- package/dist/server/create-sdk.js +0 -104
- package/dist/server/create-sdk.js.map +0 -1
- package/dist/server/from-license.d.ts +0 -252
- package/dist/server/from-license.d.ts.map +0 -1
- package/dist/server/from-license.js +0 -349
- package/dist/server/from-license.js.map +0 -1
- package/dist/server/handlers.d.ts +0 -312
- package/dist/server/handlers.d.ts.map +0 -1
- package/dist/server/handlers.js +0 -376
- package/dist/server/handlers.js.map +0 -1
- package/dist/server/postmessage-handler.d.ts +0 -152
- package/dist/server/postmessage-handler.d.ts.map +0 -1
- package/dist/server/postmessage-handler.js +0 -138
- package/dist/server/postmessage-handler.js.map +0 -1
- package/dist/transports/http.d.ts +0 -86
- package/dist/transports/http.d.ts.map +0 -1
- package/dist/transports/http.js +0 -137
- package/dist/transports/http.js.map +0 -1
- package/dist/transports/postmessage.d.ts +0 -159
- package/dist/transports/postmessage.d.ts.map +0 -1
- package/dist/transports/postmessage.js +0 -207
- package/dist/transports/postmessage.js.map +0 -1
- package/dist/transports/workshop.d.ts +0 -173
- package/dist/transports/workshop.d.ts.map +0 -1
- package/dist/transports/workshop.js +0 -307
- package/dist/transports/workshop.js.map +0 -1
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module billing/firestore-provider
|
|
3
|
-
* @description Firestore-backed billing provider for production deployments.
|
|
4
|
-
*
|
|
5
|
-
* Reads subscription and license data from the `licenses` Firestore collection
|
|
6
|
-
* managed by Portal (`soulcraft.com`). Workshop, Venue, and Academy all write
|
|
7
|
-
* usage counters to the same document so Portal's Admin can see cross-product usage.
|
|
8
|
-
*
|
|
9
|
-
* This provider is activated when `FIREBASE_SERVICE_ACCOUNT_KEY` is set in the
|
|
10
|
-
* environment. `firebase-admin` is loaded lazily via dynamic import so that the
|
|
11
|
-
* SDK does not require the package when using the local provider.
|
|
12
|
-
*
|
|
13
|
-
* **Firestore document structure:**
|
|
14
|
-
* ```
|
|
15
|
-
* licenses/{docId}
|
|
16
|
-
* email: string (user email — used to look up the doc)
|
|
17
|
-
* product: 'workshop' | 'venue' | 'academy'
|
|
18
|
-
* status: 'active' | 'past_due' | 'canceled' | 'trialing'
|
|
19
|
-
* plan: 'standard' | 'byok'
|
|
20
|
-
* credits: {
|
|
21
|
-
* monthlyIncluded: number
|
|
22
|
-
* monthlyUsed: number (SDK increments this)
|
|
23
|
-
* topUpBalance: number (SDK decrements this)
|
|
24
|
-
* inputTokens: number
|
|
25
|
-
* outputTokens: number
|
|
26
|
-
* byModel: Record<model, { input, output }>
|
|
27
|
-
* periodStart: Timestamp
|
|
28
|
-
* periodEnd: Timestamp
|
|
29
|
-
* lastUpdated: Timestamp
|
|
30
|
-
* }
|
|
31
|
-
* stripeCustomerId: string
|
|
32
|
-
* stripeSubscriptionId: string
|
|
33
|
-
* cancelAtPeriodEnd: boolean
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* Note: The `userId` passed to provider methods is the user's email address when
|
|
37
|
-
* using Firestore, since the `licenses` collection is keyed by email. Products
|
|
38
|
-
* must pass `user.email` (not `user.id`) when constructing the SDK in Firestore mode.
|
|
39
|
-
*/
|
|
40
|
-
import { MODEL_PRICING } from './model-pricing.js';
|
|
41
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
-
// Lazy loader
|
|
43
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
44
|
-
let _db;
|
|
45
|
-
let _FieldValue;
|
|
46
|
-
async function _getFirestore() {
|
|
47
|
-
if (_db && _FieldValue)
|
|
48
|
-
return { db: _db, FieldValue: _FieldValue };
|
|
49
|
-
const key = process.env['FIREBASE_SERVICE_ACCOUNT_KEY'];
|
|
50
|
-
if (!key)
|
|
51
|
-
throw new Error('FIREBASE_SERVICE_ACCOUNT_KEY is not set — cannot use Firestore billing provider');
|
|
52
|
-
// firebase-admin is an optional peer dependency — loaded at runtime only when configured.
|
|
53
|
-
// Dynamic import via Function() avoids TS2307 (package not in devDeps).
|
|
54
|
-
// In ESM contexts (Bun, Node --experimental-vm-modules) the resolved module
|
|
55
|
-
// wraps CJS exports under a `.default` namespace — unwrap it when present.
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
|
-
const adminModule = await Function('return import("firebase-admin")')();
|
|
58
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
-
const admin = adminModule.default ?? adminModule;
|
|
60
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
-
const { getFirestore, FieldValue } = await Function('return import("firebase-admin/firestore")')();
|
|
62
|
-
if (!admin.apps?.length) {
|
|
63
|
-
admin.initializeApp({
|
|
64
|
-
credential: admin.credential.cert(JSON.parse(Buffer.from(key, 'base64').toString('utf-8'))),
|
|
65
|
-
preferRest: true, // Use REST transport — required for Bun compatibility (avoids gRPC).
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
_db = getFirestore();
|
|
69
|
-
_FieldValue = FieldValue;
|
|
70
|
-
return { db: _db, FieldValue: _FieldValue };
|
|
71
|
-
}
|
|
72
|
-
const _docCache = new Map();
|
|
73
|
-
const DOC_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
74
|
-
async function _getLicenseDoc(email) {
|
|
75
|
-
const cached = _docCache.get(email);
|
|
76
|
-
if (cached && Date.now() < cached.expiresAt)
|
|
77
|
-
return cached;
|
|
78
|
-
const { db } = await _getFirestore();
|
|
79
|
-
const snap = await db.collection('licenses')
|
|
80
|
-
.where('email', '==', email.toLowerCase())
|
|
81
|
-
.where('status', 'in', ['active', 'trialing', 'past_due'])
|
|
82
|
-
.get();
|
|
83
|
-
if (!snap.docs.length)
|
|
84
|
-
return null;
|
|
85
|
-
const doc = snap.docs[0];
|
|
86
|
-
const data = doc.data() ?? {};
|
|
87
|
-
const result = { data, docId: doc.id, ref: doc.ref, expiresAt: Date.now() + DOC_CACHE_TTL_MS };
|
|
88
|
-
_docCache.set(email, result);
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
function _invalidateCache(email) {
|
|
92
|
-
_docCache.delete(email);
|
|
93
|
-
}
|
|
94
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
95
|
-
// Period helpers
|
|
96
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
97
|
-
function _toISO(ts) {
|
|
98
|
-
if (!ts)
|
|
99
|
-
return undefined;
|
|
100
|
-
if (typeof ts === 'string')
|
|
101
|
-
return ts;
|
|
102
|
-
// Firestore Timestamp object
|
|
103
|
-
if (typeof ts === 'object' && ts !== null && 'toDate' in ts) {
|
|
104
|
-
return ts.toDate().toISOString();
|
|
105
|
-
}
|
|
106
|
-
return undefined;
|
|
107
|
-
}
|
|
108
|
-
function _currentPeriod() {
|
|
109
|
-
const d = new Date();
|
|
110
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
|
|
111
|
-
}
|
|
112
|
-
function _shouldReset(periodEnd) {
|
|
113
|
-
const iso = _toISO(periodEnd);
|
|
114
|
-
if (!iso)
|
|
115
|
-
return true;
|
|
116
|
-
return new Date() >= new Date(iso);
|
|
117
|
-
}
|
|
118
|
-
const FREE_TIER_LIMIT = 100;
|
|
119
|
-
function _estimateCostUSD(byModel) {
|
|
120
|
-
let total = 0;
|
|
121
|
-
for (const [model, counts] of Object.entries(byModel)) {
|
|
122
|
-
const pricing = MODEL_PRICING[model];
|
|
123
|
-
if (!pricing)
|
|
124
|
-
continue;
|
|
125
|
-
total += (counts.input / 1_000_000) * pricing.input;
|
|
126
|
-
total += (counts.output / 1_000_000) * pricing.output;
|
|
127
|
-
}
|
|
128
|
-
return Math.round(total * 10_000) / 10_000;
|
|
129
|
-
}
|
|
130
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
131
|
-
// Provider implementation
|
|
132
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
133
|
-
/**
|
|
134
|
-
* Firestore-backed billing provider for production deployments.
|
|
135
|
-
*
|
|
136
|
-
* The `userId` parameter on all methods must be the user's **email address**,
|
|
137
|
-
* since the Firestore `licenses` collection is indexed by email.
|
|
138
|
-
*/
|
|
139
|
-
export class FirestoreBillingProvider {
|
|
140
|
-
async checkLimit(userId, hasPersonalKey) {
|
|
141
|
-
if (hasPersonalKey) {
|
|
142
|
-
return { ok: true, remaining: Infinity, topUpBalance: 0, totalAvailable: Infinity, useTopUp: false };
|
|
143
|
-
}
|
|
144
|
-
const doc = await _getLicenseDoc(userId);
|
|
145
|
-
if (!doc) {
|
|
146
|
-
// No license — free tier.
|
|
147
|
-
return { ok: false, remaining: 0, topUpBalance: 0, totalAvailable: 0, useTopUp: false, reason: 'no_subscription' };
|
|
148
|
-
}
|
|
149
|
-
const credits = doc.data['credits'] ?? {};
|
|
150
|
-
const monthlyIncluded = credits['monthlyIncluded'] ?? FREE_TIER_LIMIT;
|
|
151
|
-
const monthlyUsed = credits['monthlyUsed'] ?? 0;
|
|
152
|
-
const topUpBalance = credits['topUpBalance'] ?? 0;
|
|
153
|
-
const periodEnd = credits['periodEnd'];
|
|
154
|
-
if (_shouldReset(periodEnd)) {
|
|
155
|
-
await this._resetPeriod(doc);
|
|
156
|
-
return { ok: true, remaining: monthlyIncluded, topUpBalance, totalAvailable: monthlyIncluded + topUpBalance, useTopUp: false };
|
|
157
|
-
}
|
|
158
|
-
const remaining = Math.max(0, monthlyIncluded - monthlyUsed);
|
|
159
|
-
const totalAvailable = remaining + topUpBalance;
|
|
160
|
-
if (remaining > 0)
|
|
161
|
-
return { ok: true, remaining, topUpBalance, totalAvailable, useTopUp: false };
|
|
162
|
-
if (topUpBalance > 0)
|
|
163
|
-
return { ok: true, remaining: 0, topUpBalance, totalAvailable, useTopUp: true };
|
|
164
|
-
return { ok: false, remaining: 0, topUpBalance: 0, totalAvailable: 0, useTopUp: false, reason: 'limit_reached' };
|
|
165
|
-
}
|
|
166
|
-
async getUsage(userId) {
|
|
167
|
-
const doc = await _getLicenseDoc(userId);
|
|
168
|
-
if (!doc) {
|
|
169
|
-
return { currentPeriod: _currentPeriod(), periodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), messagesUsed: 0, inputTokens: 0, outputTokens: 0, byModel: {}, lastUpdated: new Date().toISOString() };
|
|
170
|
-
}
|
|
171
|
-
const credits = doc.data['credits'] ?? {};
|
|
172
|
-
return {
|
|
173
|
-
currentPeriod: _currentPeriod(),
|
|
174
|
-
periodEnd: _toISO(credits['periodEnd']) ?? new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
175
|
-
messagesUsed: credits['monthlyUsed'] ?? 0,
|
|
176
|
-
inputTokens: credits['inputTokens'] ?? 0,
|
|
177
|
-
outputTokens: credits['outputTokens'] ?? 0,
|
|
178
|
-
byModel: credits['byModel'] ?? {},
|
|
179
|
-
lastUpdated: _toISO(credits['lastUpdated']) ?? new Date().toISOString(),
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
async getUsageStatus(userId, hasPersonalKey) {
|
|
183
|
-
const usage = await this.getUsage(userId);
|
|
184
|
-
const doc = await _getLicenseDoc(userId);
|
|
185
|
-
const credits = doc?.data['credits'] ?? {};
|
|
186
|
-
const topUpBalance = credits['topUpBalance'] ?? 0;
|
|
187
|
-
const monthlyIncluded = credits['monthlyIncluded'] ?? FREE_TIER_LIMIT;
|
|
188
|
-
const subscription = doc ? this._toSubscription(doc.data) : undefined;
|
|
189
|
-
if (hasPersonalKey) {
|
|
190
|
-
return { mode: 'byok', usage, limit: null, remaining: null, topUpBalance, totalAvailable: null, percentUsed: null, resetsAt: usage.periodEnd, estimatedCostUSD: _estimateCostUSD(usage.byModel), ...(subscription ? { subscription } : {}) };
|
|
191
|
-
}
|
|
192
|
-
const isSubscriber = subscription?.status === 'active' || subscription?.status === 'trialing';
|
|
193
|
-
const remaining = Math.max(0, monthlyIncluded - usage.messagesUsed);
|
|
194
|
-
const totalAvailable = remaining + topUpBalance;
|
|
195
|
-
const percentUsed = Math.round((usage.messagesUsed / monthlyIncluded) * 100);
|
|
196
|
-
return {
|
|
197
|
-
mode: isSubscriber ? 'included' : 'free',
|
|
198
|
-
usage,
|
|
199
|
-
limit: monthlyIncluded,
|
|
200
|
-
remaining,
|
|
201
|
-
topUpBalance,
|
|
202
|
-
totalAvailable,
|
|
203
|
-
percentUsed,
|
|
204
|
-
resetsAt: usage.periodEnd,
|
|
205
|
-
estimatedCostUSD: _estimateCostUSD(usage.byModel),
|
|
206
|
-
...(subscription ? { subscription } : {}),
|
|
207
|
-
isFreeUser: !isSubscriber,
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
async incrementUsage(userId, inputTokens, outputTokens, model, useTopUp) {
|
|
211
|
-
const doc = await _getLicenseDoc(userId);
|
|
212
|
-
if (!doc)
|
|
213
|
-
return; // No license doc — free tier, usage not tracked in Firestore.
|
|
214
|
-
const { FieldValue } = await _getFirestore();
|
|
215
|
-
const updates = {
|
|
216
|
-
'credits.monthlyUsed': FieldValue.increment(1),
|
|
217
|
-
'credits.inputTokens': FieldValue.increment(inputTokens),
|
|
218
|
-
'credits.outputTokens': FieldValue.increment(outputTokens),
|
|
219
|
-
[`credits.byModel.${model}.input`]: FieldValue.increment(inputTokens),
|
|
220
|
-
[`credits.byModel.${model}.output`]: FieldValue.increment(outputTokens),
|
|
221
|
-
'credits.lastUpdated': FieldValue.serverTimestamp(),
|
|
222
|
-
'updatedAt': FieldValue.serverTimestamp(),
|
|
223
|
-
};
|
|
224
|
-
if (useTopUp)
|
|
225
|
-
updates['credits.topUpBalance'] = FieldValue.increment(-1);
|
|
226
|
-
await doc.ref.update(updates);
|
|
227
|
-
_invalidateCache(userId);
|
|
228
|
-
}
|
|
229
|
-
async batchIncrementUsage(userId, batch) {
|
|
230
|
-
const doc = await _getLicenseDoc(userId);
|
|
231
|
-
if (!doc)
|
|
232
|
-
return;
|
|
233
|
-
const { FieldValue } = await _getFirestore();
|
|
234
|
-
const updates = {
|
|
235
|
-
'credits.monthlyUsed': FieldValue.increment(batch.messageCount),
|
|
236
|
-
'credits.inputTokens': FieldValue.increment(batch.inputTokens),
|
|
237
|
-
'credits.outputTokens': FieldValue.increment(batch.outputTokens),
|
|
238
|
-
'credits.lastUpdated': FieldValue.serverTimestamp(),
|
|
239
|
-
'updatedAt': FieldValue.serverTimestamp(),
|
|
240
|
-
};
|
|
241
|
-
if (batch.topUpUsed > 0)
|
|
242
|
-
updates['credits.topUpBalance'] = FieldValue.increment(-batch.topUpUsed);
|
|
243
|
-
for (const [model, counts] of Object.entries(batch.byModel)) {
|
|
244
|
-
updates[`credits.byModel.${model}.input`] = FieldValue.increment(counts.input);
|
|
245
|
-
updates[`credits.byModel.${model}.output`] = FieldValue.increment(counts.output);
|
|
246
|
-
}
|
|
247
|
-
await doc.ref.update(updates);
|
|
248
|
-
_invalidateCache(userId);
|
|
249
|
-
}
|
|
250
|
-
async getSubscription(userId) {
|
|
251
|
-
const doc = await _getLicenseDoc(userId);
|
|
252
|
-
if (!doc)
|
|
253
|
-
return undefined;
|
|
254
|
-
return this._toSubscription(doc.data);
|
|
255
|
-
}
|
|
256
|
-
async hasActiveSubscription(userId) {
|
|
257
|
-
const doc = await _getLicenseDoc(userId);
|
|
258
|
-
if (!doc)
|
|
259
|
-
return false;
|
|
260
|
-
const status = doc.data['status'];
|
|
261
|
-
return status === 'active' || status === 'trialing';
|
|
262
|
-
}
|
|
263
|
-
async getTopUpBalance(userId) {
|
|
264
|
-
const doc = await _getLicenseDoc(userId);
|
|
265
|
-
if (!doc)
|
|
266
|
-
return 0;
|
|
267
|
-
const credits = doc.data['credits'] ?? {};
|
|
268
|
-
return credits['topUpBalance'] ?? 0;
|
|
269
|
-
}
|
|
270
|
-
async canAccessPaidFeature(userId) {
|
|
271
|
-
return this.hasActiveSubscription(userId);
|
|
272
|
-
}
|
|
273
|
-
// ── Internal helpers ────────────────────────────────────────────────────
|
|
274
|
-
_toSubscription(data) {
|
|
275
|
-
const status = data['status'];
|
|
276
|
-
if (!status)
|
|
277
|
-
return undefined;
|
|
278
|
-
const stripeCustomerId = data['stripeCustomerId'];
|
|
279
|
-
const stripeSubscriptionId = data['stripeSubscriptionId'];
|
|
280
|
-
const cancelAtPeriodEnd = data['cancelAtPeriodEnd'];
|
|
281
|
-
const giftedBy = data['giftedBy'];
|
|
282
|
-
const currentPeriodEnd = _toISO(data['credits']?.['periodEnd']);
|
|
283
|
-
const giftedAt = _toISO(data['giftedAt']);
|
|
284
|
-
const expiresAt = _toISO(data['expiresAt']);
|
|
285
|
-
const note = data['note'];
|
|
286
|
-
return {
|
|
287
|
-
plan: data['plan'] ?? 'standard',
|
|
288
|
-
status: status,
|
|
289
|
-
...(stripeCustomerId ? { stripeCustomerId } : {}),
|
|
290
|
-
...(stripeSubscriptionId ? { stripeSubscriptionId } : {}),
|
|
291
|
-
...(currentPeriodEnd ? { currentPeriodEnd } : {}),
|
|
292
|
-
...(cancelAtPeriodEnd !== undefined ? { cancelAtPeriodEnd } : {}),
|
|
293
|
-
...(giftedBy ? { giftedBy } : {}),
|
|
294
|
-
...(giftedAt ? { giftedAt } : {}),
|
|
295
|
-
...(expiresAt ? { expiresAt } : {}),
|
|
296
|
-
...(note ? { note } : {}),
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
async _resetPeriod(doc) {
|
|
300
|
-
const { FieldValue } = await _getFirestore();
|
|
301
|
-
const newPeriodEnd = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
|
|
302
|
-
await doc.ref.update({
|
|
303
|
-
'credits.monthlyUsed': 0,
|
|
304
|
-
'credits.inputTokens': 0,
|
|
305
|
-
'credits.outputTokens': 0,
|
|
306
|
-
'credits.byModel': {},
|
|
307
|
-
'credits.periodStart': FieldValue.serverTimestamp(),
|
|
308
|
-
'credits.periodEnd': newPeriodEnd,
|
|
309
|
-
'credits.lastUpdated': FieldValue.serverTimestamp(),
|
|
310
|
-
'updatedAt': FieldValue.serverTimestamp(),
|
|
311
|
-
});
|
|
312
|
-
_invalidateCache(doc.docId);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
//# sourceMappingURL=firestore-provider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"firestore-provider.js","sourceRoot":"","sources":["../../../src/modules/billing/firestore-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module modules/brainy/proxy
|
|
3
|
-
* @description JavaScript Proxy factory that maps any property access chain into a
|
|
4
|
-
* transport RPC call.
|
|
5
|
-
*
|
|
6
|
-
* Accessing `sdk.brainy.vfs.readdir('/')` never enumerates the Brainy API:
|
|
7
|
-
* 1. `sdk.brainy.vfs` → new Proxy with namespace `'vfs'`
|
|
8
|
-
* 2. `.readdir` → new Proxy with namespace `'vfs.readdir'`
|
|
9
|
-
* 3. Called with `['/']` → dispatches `transport.call('vfs.readdir', ['/'])`
|
|
10
|
-
*
|
|
11
|
-
* This means every current and future Brainy method is automatically supported
|
|
12
|
-
* across all transports without any per-method wiring.
|
|
13
|
-
*
|
|
14
|
-
* Special properties handled at the root level without RPC:
|
|
15
|
-
* - `close()` → `transport.close()`
|
|
16
|
-
* - `isAlive()` → `transport.isAlive()`
|
|
17
|
-
* - `onDataChange(h)` → `transport.onEvent(h)`
|
|
18
|
-
* - `offDataChange(h)` → `transport.offEvent(h)`
|
|
19
|
-
* - `_transport` → returns the underlying transport (for `connect()` on WS)
|
|
20
|
-
* - `then` → `undefined` (prevents `await sdk.brainy` from hanging)
|
|
21
|
-
*/
|
|
22
|
-
import type { SDKTransport } from '../../transports/transport.js';
|
|
23
|
-
import type { SoulcraftBrainy } from './types.js';
|
|
24
|
-
/**
|
|
25
|
-
* Creates a `SoulcraftBrainy` proxy backed by the given transport.
|
|
26
|
-
*
|
|
27
|
-
* All property accesses on the returned object are intercepted and accumulated
|
|
28
|
-
* into a dot-separated method name; when the proxy is invoked as a function
|
|
29
|
-
* the accumulated name is dispatched to `transport.call()`.
|
|
30
|
-
*
|
|
31
|
-
* @param transport - The transport that will handle all RPC dispatches.
|
|
32
|
-
* @returns A `SoulcraftBrainy` proxy ready for Brainy API calls.
|
|
33
|
-
*
|
|
34
|
-
* @example Server-mode (local transport, zero overhead)
|
|
35
|
-
* ```typescript
|
|
36
|
-
* const brain = await pool.forUser(userId, workspaceId)
|
|
37
|
-
* const brainy = createBrainyProxy(new LocalTransport(brain))
|
|
38
|
-
* const results = await brainy.find({ query: 'candle kits' })
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* @example Client-mode (HTTP transport)
|
|
42
|
-
* ```typescript
|
|
43
|
-
* const brainy = createBrainyProxy(new HttpTransport(baseUrl, token))
|
|
44
|
-
* const entity = await brainy.get(entityId)
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
export declare function createBrainyProxy(transport: SDKTransport): SoulcraftBrainy;
|
|
48
|
-
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/modules/brainy/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAEjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,YAAY,GAAG,eAAe,CAE1E"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module modules/brainy/proxy
|
|
3
|
-
* @description JavaScript Proxy factory that maps any property access chain into a
|
|
4
|
-
* transport RPC call.
|
|
5
|
-
*
|
|
6
|
-
* Accessing `sdk.brainy.vfs.readdir('/')` never enumerates the Brainy API:
|
|
7
|
-
* 1. `sdk.brainy.vfs` → new Proxy with namespace `'vfs'`
|
|
8
|
-
* 2. `.readdir` → new Proxy with namespace `'vfs.readdir'`
|
|
9
|
-
* 3. Called with `['/']` → dispatches `transport.call('vfs.readdir', ['/'])`
|
|
10
|
-
*
|
|
11
|
-
* This means every current and future Brainy method is automatically supported
|
|
12
|
-
* across all transports without any per-method wiring.
|
|
13
|
-
*
|
|
14
|
-
* Special properties handled at the root level without RPC:
|
|
15
|
-
* - `close()` → `transport.close()`
|
|
16
|
-
* - `isAlive()` → `transport.isAlive()`
|
|
17
|
-
* - `onDataChange(h)` → `transport.onEvent(h)`
|
|
18
|
-
* - `offDataChange(h)` → `transport.offEvent(h)`
|
|
19
|
-
* - `_transport` → returns the underlying transport (for `connect()` on WS)
|
|
20
|
-
* - `then` → `undefined` (prevents `await sdk.brainy` from hanging)
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Creates a `SoulcraftBrainy` proxy backed by the given transport.
|
|
24
|
-
*
|
|
25
|
-
* All property accesses on the returned object are intercepted and accumulated
|
|
26
|
-
* into a dot-separated method name; when the proxy is invoked as a function
|
|
27
|
-
* the accumulated name is dispatched to `transport.call()`.
|
|
28
|
-
*
|
|
29
|
-
* @param transport - The transport that will handle all RPC dispatches.
|
|
30
|
-
* @returns A `SoulcraftBrainy` proxy ready for Brainy API calls.
|
|
31
|
-
*
|
|
32
|
-
* @example Server-mode (local transport, zero overhead)
|
|
33
|
-
* ```typescript
|
|
34
|
-
* const brain = await pool.forUser(userId, workspaceId)
|
|
35
|
-
* const brainy = createBrainyProxy(new LocalTransport(brain))
|
|
36
|
-
* const results = await brainy.find({ query: 'candle kits' })
|
|
37
|
-
* ```
|
|
38
|
-
*
|
|
39
|
-
* @example Client-mode (HTTP transport)
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const brainy = createBrainyProxy(new HttpTransport(baseUrl, token))
|
|
42
|
-
* const entity = await brainy.get(entityId)
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export function createBrainyProxy(transport) {
|
|
46
|
-
return _createProxy(transport, '');
|
|
47
|
-
}
|
|
48
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
49
|
-
// Internal recursive proxy factory
|
|
50
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
51
|
-
/**
|
|
52
|
-
* Recursively builds a proxy that accumulates a dot-separated namespace and
|
|
53
|
-
* dispatches RPC calls when invoked.
|
|
54
|
-
*
|
|
55
|
-
* @param transport - The underlying transport instance.
|
|
56
|
-
* @param namespace - Dot-separated method path accumulated so far (empty at root).
|
|
57
|
-
* @returns A Proxy that behaves like the Brainy API at this namespace depth.
|
|
58
|
-
*/
|
|
59
|
-
function _createProxy(transport, namespace) {
|
|
60
|
-
// Use a no-op function as the Proxy target so the Proxy is callable.
|
|
61
|
-
return new Proxy(function () { }, {
|
|
62
|
-
get(_target, prop) {
|
|
63
|
-
// Pass through symbols — avoids breaking spread, iteration, Symbol.toPrimitive, etc.
|
|
64
|
-
if (typeof prop === 'symbol')
|
|
65
|
-
return undefined;
|
|
66
|
-
// Prevent accidental Promise treatment: `await sdk.brainy` must not hang.
|
|
67
|
-
if (prop === 'then')
|
|
68
|
-
return undefined;
|
|
69
|
-
const propStr = String(prop);
|
|
70
|
-
// Root-level special cases — resolved locally, never sent over the wire.
|
|
71
|
-
if (namespace === '') {
|
|
72
|
-
if (propStr === 'close')
|
|
73
|
-
return () => transport.close();
|
|
74
|
-
if (propStr === 'isAlive')
|
|
75
|
-
return () => transport.isAlive();
|
|
76
|
-
if (propStr === 'onDataChange') {
|
|
77
|
-
return (h) => transport.onEvent(h);
|
|
78
|
-
}
|
|
79
|
-
if (propStr === 'offDataChange') {
|
|
80
|
-
return (h) => transport.offEvent(h);
|
|
81
|
-
}
|
|
82
|
-
// Expose the underlying transport for callers needing connect() on WsTransport.
|
|
83
|
-
if (propStr === '_transport')
|
|
84
|
-
return transport;
|
|
85
|
-
}
|
|
86
|
-
const nextNamespace = namespace ? `${namespace}.${propStr}` : propStr;
|
|
87
|
-
return _createProxy(transport, nextNamespace);
|
|
88
|
-
},
|
|
89
|
-
apply(_target, _thisArg, args) {
|
|
90
|
-
// The proxy was invoked as a function — dispatch as an RPC call.
|
|
91
|
-
return transport.call(namespace, args);
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
//# sourceMappingURL=proxy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../../src/modules/brainy/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAuB;IACvD,OAAO,YAAY,CAAC,SAAS,EAAE,EAAE,CAAoB,CAAA;AACvD,CAAC;AAED,gFAAgF;AAChF,mCAAmC;AACnC,gFAAgF;AAEhF;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,SAAuB,EAAE,SAAiB;IAC9D,qEAAqE;IACrE,OAAO,IAAI,KAAK,CAAC,cAAa,CAAC,EAAE;QAC/B,GAAG,CAAC,OAAO,EAAE,IAAqB;YAChC,qFAAqF;YACrF,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAA;YAE9C,0EAA0E;YAC1E,IAAI,IAAI,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAA;YAErC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;YAE5B,yEAAyE;YACzE,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;gBACrB,IAAI,OAAO,KAAK,OAAO;oBAAE,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;gBACvD,IAAI,OAAO,KAAK,SAAS;oBAAE,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAA;gBAC3D,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;oBAC/B,OAAO,CAAC,CAAiC,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;gBACpE,CAAC;gBACD,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;oBAChC,OAAO,CAAC,CAAiC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;gBACrE,CAAC;gBACD,gFAAgF;gBAChF,IAAI,OAAO,KAAK,YAAY;oBAAE,OAAO,SAAS,CAAA;YAChD,CAAC;YAED,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;YACrE,OAAO,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QAC/C,CAAC;QAED,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAe;YACtC,iEAAiE;YACjE,OAAO,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QACxC,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module server/create-sdk
|
|
3
|
-
* @description `createSDK` factory for server-mode @soulcraft/sdk.
|
|
4
|
-
*
|
|
5
|
-
* Assembles a complete `SoulcraftSDK` instance from a live Brainy instance.
|
|
6
|
-
* In server mode the SDK uses the {@link LocalTransport} — zero overhead, no
|
|
7
|
-
* serialization, in-process method dispatch directly into the Brainy instance.
|
|
8
|
-
*
|
|
9
|
-
* The returned SDK object is scoped to a single Brainy instance. In a typical
|
|
10
|
-
* server request handler the caller resolves the correct Brainy instance from a
|
|
11
|
-
* {@link BrainyInstancePool} and then calls `createSDK({ brain })`. A new SDK
|
|
12
|
-
* object per request is cheap — it's a thin wrapper, not a connection.
|
|
13
|
-
*
|
|
14
|
-
* @example Workshop request handler
|
|
15
|
-
* ```typescript
|
|
16
|
-
* import { BrainyInstancePool, createSDK } from '@soulcraft/sdk/server'
|
|
17
|
-
*
|
|
18
|
-
* const pool = new BrainyInstancePool({ storage: 'filesystem', dataPath: './data', strategy: 'per-user' })
|
|
19
|
-
*
|
|
20
|
-
* app.get('/api/inventory', requireAuth, async (c) => {
|
|
21
|
-
* const user = c.get('user')!
|
|
22
|
-
* const brain = await pool.forUser(user.emailHash, 'main')
|
|
23
|
-
* const sdk = createSDK({ brain })
|
|
24
|
-
*
|
|
25
|
-
* const items = await sdk.brainy.find({ query: 'inventory items', type: 'Product' })
|
|
26
|
-
* const readme = await sdk.vfs.readFile('/projects/my-project/README.md')
|
|
27
|
-
* return c.json({ items })
|
|
28
|
-
* })
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
import type { Brainy } from '@soulcraft/brainy';
|
|
32
|
-
import type { SoulcraftSDK } from '../types.js';
|
|
33
|
-
/**
|
|
34
|
-
* Options for the server-mode {@link createSDK} factory.
|
|
35
|
-
*/
|
|
36
|
-
export interface CreateSDKOptions {
|
|
37
|
-
/**
|
|
38
|
-
* A fully initialized Brainy instance.
|
|
39
|
-
*
|
|
40
|
-
* Typically resolved from a {@link BrainyInstancePool} for the current user
|
|
41
|
-
* or tenant. The SDK wraps this instance in a {@link LocalTransport} so all
|
|
42
|
-
* `sdk.brainy.*` and `sdk.vfs.*` calls dispatch directly into it.
|
|
43
|
-
*/
|
|
44
|
-
brain: Brainy;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Create a server-mode `SoulcraftSDK` wrapping a live Brainy instance.
|
|
48
|
-
*
|
|
49
|
-
* All `sdk.brainy.*` and `sdk.vfs.*` calls are dispatched in-process with zero
|
|
50
|
-
* serialization overhead via {@link LocalTransport}.
|
|
51
|
-
*
|
|
52
|
-
* `sdk.ai.*` calls go directly to the Anthropic API (requires `ANTHROPIC_API_KEY`).
|
|
53
|
-
* `sdk.skills.*` reads from the Brainy VFS and falls back to `@soulcraft/kits`.
|
|
54
|
-
* `sdk.events` is a local EventEmitter — events do not cross process boundaries.
|
|
55
|
-
* `sdk.billing.*` stores usage locally (dev) or via Portal credits (prod via `PORTAL_CREDIT_SECRET`).
|
|
56
|
-
* `sdk.license.*` activates via `@soulcraft/cortex` and delegates credit metering to `sdk.billing`.
|
|
57
|
-
* `sdk.kits.*` reads from the `@soulcraft/kits` registry (optional peer dependency).
|
|
58
|
-
* `sdk.notifications.*` sends via Postmark/Twilio or logs to the console in dev mode.
|
|
59
|
-
*
|
|
60
|
-
* @param options - SDK creation options.
|
|
61
|
-
* @returns A fully assembled `SoulcraftSDK` instance.
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```typescript
|
|
65
|
-
* const brain = await pool.forUser(user.emailHash, workspaceId)
|
|
66
|
-
* const sdk = createSDK({ brain })
|
|
67
|
-
*
|
|
68
|
-
* const results = await sdk.brainy.find({ query: 'candle inventory' })
|
|
69
|
-
* const readme = await sdk.vfs.readFile('/projects/README.md')
|
|
70
|
-
* await sdk.events.emit('kit:session-completed', { userId, sessionId, kitId })
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
export declare function createSDK(options: CreateSDKOptions): SoulcraftSDK;
|
|
74
|
-
//# sourceMappingURL=create-sdk.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-sdk.d.ts","sourceRoot":"","sources":["../../src/server/create-sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAW/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO/C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;CACd;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAoCjE"}
|