@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.
Files changed (72) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +874 -0
  3. package/dist/index.js +999 -0
  4. package/dist/modules/analytics.js +584 -0
  5. package/dist/modules/auth.js +469 -0
  6. package/dist/modules/bindings.js +319 -0
  7. package/dist/modules/device.js +282 -0
  8. package/dist/modules/dom.js +96 -0
  9. package/dist/modules/features.js +30 -0
  10. package/dist/modules/firestore.js +313 -0
  11. package/dist/modules/form-manager.js +1577 -0
  12. package/dist/modules/icon-core.js +226 -0
  13. package/dist/modules/icon-renderer.js +149 -0
  14. package/dist/modules/live-page.js +235 -0
  15. package/dist/modules/logger.js +36 -0
  16. package/dist/modules/motion.js +853 -0
  17. package/dist/modules/notifications.js +433 -0
  18. package/dist/modules/path-prefix.js +22 -0
  19. package/dist/modules/request.js +223 -0
  20. package/dist/modules/sentry.js +108 -0
  21. package/dist/modules/service-worker.js +237 -0
  22. package/dist/modules/storage.js +133 -0
  23. package/dist/modules/triggers.js +117 -0
  24. package/dist/modules/utilities.js +479 -0
  25. package/dist/modules/vert-document.js +354 -0
  26. package/dist/modules/verts.js +1133 -0
  27. package/dist/vendor/account/engine.js +182 -0
  28. package/dist/vendor/account/features.js +220 -0
  29. package/dist/vendor/account/index.js +53 -0
  30. package/dist/vendor/account/schema.js +272 -0
  31. package/dist/vendor/account/subscription.js +38 -0
  32. package/dist/vendor/analytics/adapters/ga4.js +26 -0
  33. package/dist/vendor/analytics/adapters/meta.js +26 -0
  34. package/dist/vendor/analytics/adapters/resolve.js +130 -0
  35. package/dist/vendor/analytics/adapters/tiktok.js +27 -0
  36. package/dist/vendor/analytics/catalog.js +908 -0
  37. package/dist/vendor/analytics/consent.js +49 -0
  38. package/dist/vendor/analytics/core.js +141 -0
  39. package/dist/vendor/analytics/identity.js +136 -0
  40. package/dist/vendor/analytics/index.js +170 -0
  41. package/dist/vendor/analytics/logger.js +40 -0
  42. package/dist/vendor/analytics/transports/browser.js +110 -0
  43. package/dist/vendor/monitoring/browser.js +207 -0
  44. package/dist/vendor/monitoring/core.js +180 -0
  45. package/dist/vendor/monitoring/logger.js +39 -0
  46. package/docs/architecture.md +59 -0
  47. package/docs/bindings.md +235 -0
  48. package/docs/build-system.md +32 -0
  49. package/docs/cdp-debugging.md +29 -0
  50. package/docs/code-patterns.md +96 -0
  51. package/docs/common-tasks.md +36 -0
  52. package/docs/dependencies.md +19 -0
  53. package/docs/index.md +159 -0
  54. package/docs/modules.md +180 -0
  55. package/docs/shared/agent-docs.md +89 -0
  56. package/docs/shared/analytics.md +612 -0
  57. package/docs/shared/brands.md +51 -0
  58. package/docs/shared/breaking-changes.md +497 -0
  59. package/docs/shared/config.md +1387 -0
  60. package/docs/shared/deploys.md +215 -0
  61. package/docs/shared/icons.md +201 -0
  62. package/docs/shared/local-dev.md +147 -0
  63. package/docs/shared/logging.md +202 -0
  64. package/docs/shared/monitoring.md +153 -0
  65. package/docs/shared/publishing.md +183 -0
  66. package/docs/shared/rulings.md +34 -0
  67. package/docs/shared/testing.md +147 -0
  68. package/docs/shared/theming.md +604 -0
  69. package/docs/shared/translation.md +291 -0
  70. package/docs/shared/updates.md +61 -0
  71. package/docs/testing.md +9 -0
  72. 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;