@omega.js/client 0.1.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 +98 -0
- package/README.md +874 -0
- package/dist/index.js +999 -0
- package/dist/modules/analytics.js +584 -0
- package/dist/modules/auth.js +469 -0
- package/dist/modules/bindings.js +319 -0
- package/dist/modules/device.js +282 -0
- package/dist/modules/dom.js +96 -0
- package/dist/modules/features.js +30 -0
- package/dist/modules/firestore.js +313 -0
- package/dist/modules/form-manager.js +1577 -0
- package/dist/modules/icon-core.js +226 -0
- package/dist/modules/icon-renderer.js +149 -0
- package/dist/modules/live-page.js +235 -0
- package/dist/modules/logger.js +36 -0
- package/dist/modules/motion.js +853 -0
- package/dist/modules/notifications.js +433 -0
- package/dist/modules/path-prefix.js +22 -0
- package/dist/modules/request.js +223 -0
- package/dist/modules/sentry.js +108 -0
- package/dist/modules/service-worker.js +237 -0
- package/dist/modules/storage.js +133 -0
- package/dist/modules/triggers.js +117 -0
- package/dist/modules/utilities.js +479 -0
- package/dist/modules/vert-document.js +354 -0
- package/dist/modules/verts.js +1133 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/analytics/adapters/ga4.js +26 -0
- package/dist/vendor/analytics/adapters/meta.js +26 -0
- package/dist/vendor/analytics/adapters/resolve.js +130 -0
- package/dist/vendor/analytics/adapters/tiktok.js +27 -0
- package/dist/vendor/analytics/catalog.js +908 -0
- package/dist/vendor/analytics/consent.js +49 -0
- package/dist/vendor/analytics/core.js +141 -0
- package/dist/vendor/analytics/identity.js +136 -0
- package/dist/vendor/analytics/index.js +170 -0
- package/dist/vendor/analytics/logger.js +40 -0
- package/dist/vendor/analytics/transports/browser.js +110 -0
- package/dist/vendor/monitoring/browser.js +207 -0
- package/dist/vendor/monitoring/core.js +180 -0
- package/dist/vendor/monitoring/logger.js +39 -0
- package/docs/architecture.md +59 -0
- package/docs/bindings.md +235 -0
- package/docs/build-system.md +32 -0
- package/docs/cdp-debugging.md +29 -0
- package/docs/code-patterns.md +96 -0
- package/docs/common-tasks.md +36 -0
- package/docs/dependencies.md +19 -0
- package/docs/index.md +159 -0
- package/docs/modules.md +180 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/testing.md +9 -0
- package/package.json +65 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* features — the features contract, reachable from a page
|
|
3
|
+
* ([#647](https://github.com/Omega-JS-Stack/omega/issues/647)).
|
|
4
|
+
*
|
|
5
|
+
* The derivations live ONCE, in `@omega.js/account` — the same module
|
|
6
|
+
* @omega.js/backend's `consume` gate reads — so the number that refuses a
|
|
7
|
+
* request and the number a usage bar draws can never be two different numbers:
|
|
8
|
+
* the effective limit (a per-user `usage.overrides.<feature>` wins over the
|
|
9
|
+
* plan's), the day's share of a month limit, and what is left of each.
|
|
10
|
+
*
|
|
11
|
+
* This module is the door a frontend goes through. `@omega.js/account` is a
|
|
12
|
+
* private package a consumer's install never resolves by name, and this
|
|
13
|
+
* package's dist carries it vendored — exactly the way `modules/analytics.js`
|
|
14
|
+
* fronts `@omega.js/analytics`.
|
|
15
|
+
*
|
|
16
|
+
* The catalog itself is CONFIG: `omega.config.features`, which the embedding
|
|
17
|
+
* framework's build bridges in beside `omega.config.payment`.
|
|
18
|
+
*/
|
|
19
|
+
export {
|
|
20
|
+
isCountedFeature,
|
|
21
|
+
isPacedFeature,
|
|
22
|
+
featureMirrors,
|
|
23
|
+
featureOverride,
|
|
24
|
+
featureCounters,
|
|
25
|
+
productFeatureValue,
|
|
26
|
+
daysInMonth,
|
|
27
|
+
dayShare,
|
|
28
|
+
resolveFeature,
|
|
29
|
+
resolveFeatures,
|
|
30
|
+
} from '../vendor/account/features.js';
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
class Firestore {
|
|
2
|
+
constructor(manager) {
|
|
3
|
+
this.manager = manager;
|
|
4
|
+
this._db = null;
|
|
5
|
+
this._initialized = false;
|
|
6
|
+
this._initPromise = null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async _ensureInitialized() {
|
|
10
|
+
if (this._initialized) {
|
|
11
|
+
return this._db;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!this._initPromise) {
|
|
15
|
+
this._initPromise = this._initializeFirestore();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return this._initPromise;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async _initializeFirestore() {
|
|
22
|
+
try {
|
|
23
|
+
// Check if Firebase app is initialized
|
|
24
|
+
if (!this.manager._firebaseApp) {
|
|
25
|
+
throw new Error('Firebase app not initialized. Please initialize Firebase first.');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Dynamically import Firestore
|
|
29
|
+
const { getFirestore, doc: firestoreDoc, collection: firestoreCollection, getDoc, setDoc, updateDoc, deleteDoc, getDocs, query, where, orderBy, limit, startAt, endAt, onSnapshot } = await import('firebase/firestore');
|
|
30
|
+
|
|
31
|
+
// Store references for later use
|
|
32
|
+
this._firestoreMethods = {
|
|
33
|
+
doc: firestoreDoc,
|
|
34
|
+
collection: firestoreCollection,
|
|
35
|
+
getDoc,
|
|
36
|
+
setDoc,
|
|
37
|
+
updateDoc,
|
|
38
|
+
deleteDoc,
|
|
39
|
+
getDocs,
|
|
40
|
+
query,
|
|
41
|
+
where,
|
|
42
|
+
orderBy,
|
|
43
|
+
limit,
|
|
44
|
+
startAt,
|
|
45
|
+
endAt,
|
|
46
|
+
onSnapshot,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Reuse the Firestore instance already initialized in index.js — emulator
|
|
50
|
+
// connection (when enabled) already happened there, at creation time.
|
|
51
|
+
this._db = getFirestore(this.manager._firebaseApp);
|
|
52
|
+
|
|
53
|
+
this._initialized = true;
|
|
54
|
+
|
|
55
|
+
return this._db;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('Failed to initialize Firestore:', error);
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Main doc() method - supports both 'path/to/doc' and ('collection', 'docId')
|
|
63
|
+
doc(...args) {
|
|
64
|
+
const self = this;
|
|
65
|
+
let docPath;
|
|
66
|
+
|
|
67
|
+
// Handle different argument patterns
|
|
68
|
+
if (args.length === 1 && typeof args[0] === 'string') {
|
|
69
|
+
// Single path string: doc('users/userId')
|
|
70
|
+
docPath = args[0];
|
|
71
|
+
} else if (args.length === 2 && typeof args[0] === 'string' && typeof args[1] === 'string') {
|
|
72
|
+
// Collection and doc ID: doc('users', 'userId')
|
|
73
|
+
docPath = `${args[0]}/${args[1]}`;
|
|
74
|
+
} else {
|
|
75
|
+
throw new Error('Invalid arguments for doc(). Use doc("path/to/doc") or doc("collection", "docId")');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
async get() {
|
|
80
|
+
await self._ensureInitialized();
|
|
81
|
+
const docRef = self._firestoreMethods.doc(self._db, docPath);
|
|
82
|
+
const docSnap = await self._firestoreMethods.getDoc(docRef);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
exists: () => docSnap.exists(),
|
|
86
|
+
data: () => docSnap.data(),
|
|
87
|
+
id: docSnap.id,
|
|
88
|
+
ref: docRef
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
async set(data, options = {}) {
|
|
93
|
+
await self._ensureInitialized();
|
|
94
|
+
const docRef = self._firestoreMethods.doc(self._db, docPath);
|
|
95
|
+
return await self._firestoreMethods.setDoc(docRef, data, options);
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
async update(data) {
|
|
99
|
+
await self._ensureInitialized();
|
|
100
|
+
const docRef = self._firestoreMethods.doc(self._db, docPath);
|
|
101
|
+
return await self._firestoreMethods.updateDoc(docRef, data);
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
async delete() {
|
|
105
|
+
await self._ensureInitialized();
|
|
106
|
+
const docRef = self._firestoreMethods.doc(self._db, docPath);
|
|
107
|
+
return await self._firestoreMethods.deleteDoc(docRef);
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
onSnapshot(callback, errorCallback) {
|
|
111
|
+
// Cancellation-safe lazy subscribe: unsubscribing before init
|
|
112
|
+
// resolves must stop the listener from ever attaching — a
|
|
113
|
+
// placeholder noop would let it attach undetachably.
|
|
114
|
+
let cancelled = false;
|
|
115
|
+
let unsubscribe = null;
|
|
116
|
+
|
|
117
|
+
self._ensureInitialized().then(function () {
|
|
118
|
+
if (cancelled) return;
|
|
119
|
+
const docRef = self._firestoreMethods.doc(self._db, docPath);
|
|
120
|
+
|
|
121
|
+
unsubscribe = self._firestoreMethods.onSnapshot(docRef, function (docSnap) {
|
|
122
|
+
callback({
|
|
123
|
+
exists: () => docSnap.exists(),
|
|
124
|
+
data: () => docSnap.data(),
|
|
125
|
+
id: docSnap.id,
|
|
126
|
+
ref: docRef,
|
|
127
|
+
});
|
|
128
|
+
}, errorCallback);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return function () {
|
|
132
|
+
cancelled = true;
|
|
133
|
+
if (unsubscribe) unsubscribe();
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Collection method for queries
|
|
140
|
+
collection(collectionPath) {
|
|
141
|
+
const self = this;
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
async get() {
|
|
145
|
+
await self._ensureInitialized();
|
|
146
|
+
const collRef = self._firestoreMethods.collection(self._db, collectionPath);
|
|
147
|
+
const querySnapshot = await self._firestoreMethods.getDocs(collRef);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
docs: querySnapshot.docs.map(doc => ({
|
|
151
|
+
id: doc.id,
|
|
152
|
+
data: () => doc.data(),
|
|
153
|
+
exists: () => doc.exists(),
|
|
154
|
+
ref: doc.ref
|
|
155
|
+
})),
|
|
156
|
+
size: querySnapshot.size,
|
|
157
|
+
empty: querySnapshot.empty,
|
|
158
|
+
forEach: (callback) => querySnapshot.forEach(callback)
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
where(field, operator, value) {
|
|
163
|
+
return self._buildQuery(collectionPath, [{ type: 'where', field, operator, value }]);
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
orderBy(field, direction = 'asc') {
|
|
167
|
+
return self._buildQuery(collectionPath, [{ type: 'orderBy', field, direction }]);
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
limit(count) {
|
|
171
|
+
return self._buildQuery(collectionPath, [{ type: 'limit', count }]);
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
doc(docId) {
|
|
175
|
+
if (docId) {
|
|
176
|
+
return self.doc(`${collectionPath}/${docId}`);
|
|
177
|
+
}
|
|
178
|
+
// Auto-generate ID if not provided
|
|
179
|
+
return self.doc(`${collectionPath}/${self._generateId()}`);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Build chainable query
|
|
185
|
+
_buildQuery(collectionPath, constraints = []) {
|
|
186
|
+
const self = this;
|
|
187
|
+
|
|
188
|
+
const queryBuilder = {
|
|
189
|
+
where(field, operator, value) {
|
|
190
|
+
constraints.push({ type: 'where', field, operator, value });
|
|
191
|
+
return queryBuilder;
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
orderBy(field, direction = 'asc') {
|
|
195
|
+
constraints.push({ type: 'orderBy', field, direction });
|
|
196
|
+
return queryBuilder;
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
limit(count) {
|
|
200
|
+
constraints.push({ type: 'limit', count });
|
|
201
|
+
return queryBuilder;
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
startAt(...values) {
|
|
205
|
+
constraints.push({ type: 'startAt', values });
|
|
206
|
+
return queryBuilder;
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
endAt(...values) {
|
|
210
|
+
constraints.push({ type: 'endAt', values });
|
|
211
|
+
return queryBuilder;
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
async get() {
|
|
215
|
+
return self._executeQuery(collectionPath, constraints);
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
onSnapshot(callback, errorCallback) {
|
|
219
|
+
// Same cancellation-safe pattern as the doc onSnapshot above
|
|
220
|
+
let cancelled = false;
|
|
221
|
+
let unsubscribe = null;
|
|
222
|
+
|
|
223
|
+
self._ensureInitialized().then(function () {
|
|
224
|
+
if (cancelled) return;
|
|
225
|
+
const collRef = self._firestoreMethods.collection(self._db, collectionPath);
|
|
226
|
+
const queryConstraints = self._buildConstraints(constraints);
|
|
227
|
+
const q = self._firestoreMethods.query(collRef, ...queryConstraints);
|
|
228
|
+
|
|
229
|
+
unsubscribe = self._firestoreMethods.onSnapshot(q, function (querySnapshot) {
|
|
230
|
+
callback({
|
|
231
|
+
docs: querySnapshot.docs.map(doc => ({
|
|
232
|
+
id: doc.id,
|
|
233
|
+
data: () => doc.data(),
|
|
234
|
+
exists: () => doc.exists(),
|
|
235
|
+
ref: doc.ref,
|
|
236
|
+
})),
|
|
237
|
+
size: querySnapshot.size,
|
|
238
|
+
empty: querySnapshot.empty,
|
|
239
|
+
forEach: (cb) => querySnapshot.forEach(cb),
|
|
240
|
+
});
|
|
241
|
+
}, errorCallback);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return function () {
|
|
245
|
+
cancelled = true;
|
|
246
|
+
if (unsubscribe) unsubscribe();
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
return queryBuilder;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Build query constraint objects from constraint descriptors
|
|
255
|
+
_buildConstraints(constraints) {
|
|
256
|
+
const queryConstraints = [];
|
|
257
|
+
|
|
258
|
+
for (const constraint of constraints) {
|
|
259
|
+
switch (constraint.type) {
|
|
260
|
+
case 'where':
|
|
261
|
+
queryConstraints.push(this._firestoreMethods.where(constraint.field, constraint.operator, constraint.value));
|
|
262
|
+
break;
|
|
263
|
+
case 'orderBy':
|
|
264
|
+
queryConstraints.push(this._firestoreMethods.orderBy(constraint.field, constraint.direction));
|
|
265
|
+
break;
|
|
266
|
+
case 'limit':
|
|
267
|
+
queryConstraints.push(this._firestoreMethods.limit(constraint.count));
|
|
268
|
+
break;
|
|
269
|
+
case 'startAt':
|
|
270
|
+
queryConstraints.push(this._firestoreMethods.startAt(...constraint.values));
|
|
271
|
+
break;
|
|
272
|
+
case 'endAt':
|
|
273
|
+
queryConstraints.push(this._firestoreMethods.endAt(...constraint.values));
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return queryConstraints;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Execute a query and return formatted results
|
|
282
|
+
async _executeQuery(collectionPath, constraints) {
|
|
283
|
+
await this._ensureInitialized();
|
|
284
|
+
const collRef = this._firestoreMethods.collection(this._db, collectionPath);
|
|
285
|
+
const queryConstraints = this._buildConstraints(constraints);
|
|
286
|
+
const q = this._firestoreMethods.query(collRef, ...queryConstraints);
|
|
287
|
+
const querySnapshot = await this._firestoreMethods.getDocs(q);
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
docs: querySnapshot.docs.map(doc => ({
|
|
291
|
+
id: doc.id,
|
|
292
|
+
data: () => doc.data(),
|
|
293
|
+
exists: () => doc.exists(),
|
|
294
|
+
ref: doc.ref,
|
|
295
|
+
})),
|
|
296
|
+
size: querySnapshot.size,
|
|
297
|
+
empty: querySnapshot.empty,
|
|
298
|
+
forEach: (callback) => querySnapshot.forEach(callback),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Helper to generate document IDs (similar to Firebase auto-generated IDs)
|
|
303
|
+
_generateId() {
|
|
304
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
305
|
+
let id = '';
|
|
306
|
+
for (let i = 0; i < 20; i++) {
|
|
307
|
+
id += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
308
|
+
}
|
|
309
|
+
return id;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export default Firestore;
|