@iebh/tera-fy 2.0.21 → 2.2.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 (75) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/api.md +68 -66
  3. package/dist/lib/projectFile.d.ts +182 -0
  4. package/dist/lib/projectFile.js +157 -0
  5. package/dist/lib/projectFile.js.map +1 -0
  6. package/dist/lib/syncro/entities.d.ts +28 -0
  7. package/dist/lib/syncro/entities.js +203 -0
  8. package/dist/lib/syncro/entities.js.map +1 -0
  9. package/dist/lib/syncro/keyed.d.ts +95 -0
  10. package/dist/lib/syncro/keyed.js +286 -0
  11. package/dist/lib/syncro/keyed.js.map +1 -0
  12. package/dist/lib/syncro/syncro.d.ts +328 -0
  13. package/dist/lib/syncro/syncro.js +633 -0
  14. package/dist/lib/syncro/syncro.js.map +1 -0
  15. package/dist/lib/terafy.bootstrapper.d.ts +42 -0
  16. package/dist/lib/terafy.bootstrapper.js +130 -0
  17. package/dist/lib/terafy.bootstrapper.js.map +1 -0
  18. package/dist/lib/terafy.client.d.ts +532 -0
  19. package/dist/lib/terafy.client.js +1110 -0
  20. package/dist/lib/terafy.client.js.map +1 -0
  21. package/dist/lib/terafy.proxy.d.ts +66 -0
  22. package/dist/lib/terafy.proxy.js +123 -0
  23. package/dist/lib/terafy.proxy.js.map +1 -0
  24. package/dist/lib/terafy.server.d.ts +607 -0
  25. package/dist/lib/terafy.server.js +1774 -0
  26. package/dist/lib/terafy.server.js.map +1 -0
  27. package/dist/plugin.vue2.es2019.js +30 -13
  28. package/dist/plugins/base.d.ts +20 -0
  29. package/dist/plugins/base.js +21 -0
  30. package/dist/plugins/base.js.map +1 -0
  31. package/dist/plugins/firebase.d.ts +62 -0
  32. package/dist/plugins/firebase.js +111 -0
  33. package/dist/plugins/firebase.js.map +1 -0
  34. package/dist/plugins/vite.d.ts +12 -0
  35. package/dist/plugins/vite.js +22 -0
  36. package/dist/plugins/vite.js.map +1 -0
  37. package/dist/plugins/vue2.d.ts +68 -0
  38. package/dist/plugins/vue2.js +96 -0
  39. package/dist/plugins/vue2.js.map +1 -0
  40. package/dist/plugins/vue3.d.ts +64 -0
  41. package/dist/plugins/vue3.js +96 -0
  42. package/dist/plugins/vue3.js.map +1 -0
  43. package/dist/terafy.bootstrapper.es2019.js +2 -2
  44. package/dist/terafy.bootstrapper.js +2 -2
  45. package/dist/terafy.es2019.js +2 -2
  46. package/dist/terafy.js +1 -1
  47. package/dist/utils/mixin.d.ts +11 -0
  48. package/dist/utils/mixin.js +15 -0
  49. package/dist/utils/mixin.js.map +1 -0
  50. package/dist/utils/pDefer.d.ts +12 -0
  51. package/dist/utils/pDefer.js +14 -0
  52. package/dist/utils/pDefer.js.map +1 -0
  53. package/dist/utils/pathTools.d.ts +70 -0
  54. package/dist/utils/pathTools.js +120 -0
  55. package/dist/utils/pathTools.js.map +1 -0
  56. package/eslint.config.js +44 -8
  57. package/lib/{projectFile.js → projectFile.ts} +83 -40
  58. package/lib/syncro/entities.ts +288 -0
  59. package/lib/syncro/{keyed.js → keyed.ts} +114 -57
  60. package/lib/syncro/{syncro.js → syncro.ts} +204 -169
  61. package/lib/{terafy.bootstrapper.js → terafy.bootstrapper.ts} +49 -31
  62. package/lib/{terafy.client.js → terafy.client.ts} +94 -86
  63. package/lib/{terafy.proxy.js → terafy.proxy.ts} +43 -16
  64. package/lib/{terafy.server.js → terafy.server.ts} +364 -223
  65. package/package.json +65 -26
  66. package/plugins/{base.js → base.ts} +3 -1
  67. package/plugins/{firebase.js → firebase.ts} +34 -16
  68. package/plugins/{vite.js → vite.ts} +3 -3
  69. package/plugins/{vue2.js → vue2.ts} +17 -10
  70. package/plugins/{vue3.js → vue3.ts} +11 -9
  71. package/tsconfig.json +30 -0
  72. package/utils/{mixin.js → mixin.ts} +1 -1
  73. package/utils/{pDefer.js → pDefer.ts} +10 -3
  74. package/utils/{pathTools.js → pathTools.ts} +11 -9
  75. package/lib/syncro/entities.js +0 -232
@@ -0,0 +1,95 @@
1
+ import Syncro from './syncro.js';
2
+ interface FlushOptions {
3
+ destroy?: boolean;
4
+ }
5
+ /**
6
+ * @class SyncroKeyed
7
+ * TERA Isomorphic SyncroKeyed class
8
+ * Collate a single (potencially very large) single Syncro object by spltting it acrtoss multiple Syncros
9
+ * This makes the assumption that the Syncro content is a large object collection of objects - a keyed map collection
10
+ * The original impetus is to allow TERA citation libraries to be held in a Syncro object and flushed back to Supabase when editing has completed
11
+ */
12
+ export default class SyncroKeyed extends Syncro {
13
+ /**
14
+ * Config used by this instance to configure behaviour
15
+ *
16
+ * @type {Object}
17
+ * @property {Number} maxKeys The maximum number of keys a member can contain before needing to add a member
18
+ */
19
+ keyedConfig: {
20
+ maxKeys: number;
21
+ };
22
+ /**
23
+ * Various storage about keyed path
24
+ */
25
+ keyedPath: {
26
+ getKey(path: string, index: number): string;
27
+ };
28
+ /**
29
+ * Member Syncros which form part of this meta Syncro
30
+ *
31
+ * @type {Array<Syncro>}
32
+ */
33
+ members: Syncro[];
34
+ /**
35
+ * Instance constructor
36
+ *
37
+ * @param {String} path Mount path for the Syncro. Should be in the form `${ENTITY}::${ID}(::${RELATION})?_*` (must contain a '*' operator)
38
+ * @param {Object} [options] Additional instance setters (mutates instance directly)
39
+ */
40
+ constructor(path: string, options?: Record<string, any>);
41
+ /**
42
+ * Destroy all Syncro members
43
+ *
44
+ * @returns {Promise} A promise which resolves when the operation has completed
45
+ */
46
+ destroy(): Promise<never[]>;
47
+ /**
48
+ * Mount this SyncroKeyed instance
49
+ * i.e. Fetch all members and mount them locally creating a Proxy
50
+ *
51
+ * @returns {Promise<Syncro>} A promise which resolves as this SyncroKeyed instance when completed
52
+ */
53
+ mount(): Promise<Syncro>;
54
+ /**
55
+ * Return a Proxy which will map setter/getter actions to their correct member
56
+ *
57
+ * @returns {Proxy} A proxy of all combined members
58
+ */
59
+ proxy(): Record<string | symbol, any>;
60
+ /**
61
+ * Flush all member states
62
+ *
63
+ * @param {Object} [options] Additional options to mutate behaviour
64
+ * @param {Boolean} [options.destroy=false] Instruct the server to also dispose of the Syncro state
65
+ *
66
+ * @returns {Promise} A promise which resolves when the operation has completed
67
+ */
68
+ flush(options?: FlushOptions): Promise<void>;
69
+ /**
70
+ * Set a given key against the next available member
71
+ * This will either pick the next available member with keys below `config.maxKeys` or extend the member array and append to it
72
+ *
73
+ * @param {String} key The key to set
74
+ * @param {*} value The value to set
75
+ *
76
+ * @returns {Promise<*>} A promise which resolves when the operation has completed with the set value
77
+ */
78
+ keyedSet(key: string, value: any): Promise<any>;
79
+ /**
80
+ * Assign an entire in-memory object to members
81
+ * This can be thought of as the optimized equivelent of Object.assign()
82
+ * Use this when merging large objects as it can make optimizations
83
+ *
84
+ * @param {Object} state The value to merge
85
+ */
86
+ keyedAssign(state: Record<string, any>): Promise<void>;
87
+ /**
88
+ * Extend the member pool by one member
89
+ *
90
+ * @param {Number} [index] The index to use when expanding, if omitted the next index offset is used
91
+ * @returns {Promise} A promise which resolves when the operation has completed
92
+ */
93
+ keyedMembersExpand(index?: number): Promise<void>;
94
+ }
95
+ export {};
@@ -0,0 +1,286 @@
1
+ import { chunk } from 'lodash-es';
2
+ import { doc as FirestoreDocRef, getDoc as FirestoreGetDoc } from 'firebase/firestore';
3
+ import Syncro from './syncro.js';
4
+ import SyncroEntities from './entities.js';
5
+ /**
6
+ * @class SyncroKeyed
7
+ * TERA Isomorphic SyncroKeyed class
8
+ * Collate a single (potencially very large) single Syncro object by spltting it acrtoss multiple Syncros
9
+ * This makes the assumption that the Syncro content is a large object collection of objects - a keyed map collection
10
+ * The original impetus is to allow TERA citation libraries to be held in a Syncro object and flushed back to Supabase when editing has completed
11
+ */
12
+ export default class SyncroKeyed extends Syncro {
13
+ /**
14
+ * Instance constructor
15
+ *
16
+ * @param {String} path Mount path for the Syncro. Should be in the form `${ENTITY}::${ID}(::${RELATION})?_*` (must contain a '*' operator)
17
+ * @param {Object} [options] Additional instance setters (mutates instance directly)
18
+ */
19
+ constructor(path, options) {
20
+ super(path, options);
21
+ /**
22
+ * Config used by this instance to configure behaviour
23
+ *
24
+ * @type {Object}
25
+ * @property {Number} maxKeys The maximum number of keys a member can contain before needing to add a member
26
+ */
27
+ this.keyedConfig = {
28
+ maxKeys: 2,
29
+ };
30
+ /**
31
+ * Various storage about keyed path
32
+ */
33
+ this.keyedPath = {
34
+ getKey(path, index) {
35
+ return path + '_' + index;
36
+ },
37
+ };
38
+ /**
39
+ * Member Syncros which form part of this meta Syncro
40
+ *
41
+ * @type {Array<Syncro>}
42
+ */
43
+ this.members = [];
44
+ if (!/\*/.test(path))
45
+ throw new Error('SyncroKeyed paths must contain at least one asterisk as an object pagination indicator');
46
+ let { prefix, suffix } = /^(?<prefix>.+)\*(?<suffix>.*)$/.exec(path).groups;
47
+ this.keyedPath.getKey = (path, index) => `${prefix}${index}${suffix}`;
48
+ }
49
+ /**
50
+ * Destroy all Syncro members
51
+ *
52
+ * @returns {Promise} A promise which resolves when the operation has completed
53
+ */
54
+ async destroy() {
55
+ this.debug('Destroy!');
56
+ await Promise.all(this.members.map(member => member.destroy()));
57
+ this.members = [];
58
+ return []; // Return empty array cast to never[] to satisfy signature
59
+ }
60
+ /**
61
+ * Mount this SyncroKeyed instance
62
+ * i.e. Fetch all members and mount them locally creating a Proxy
63
+ *
64
+ * @returns {Promise<Syncro>} A promise which resolves as this SyncroKeyed instance when completed
65
+ */
66
+ mount() {
67
+ // Cast the result to the expected interface
68
+ let { entity, id, relation, fsCollection, fsId } = Syncro.pathSplit(this.path, { allowAsterisk: true });
69
+ return Promise.resolve()
70
+ .then(() => new Promise(resolve => {
71
+ this.members = []; // Reset member list
72
+ let seekMember = async (index) => {
73
+ let memberId = fsId.replace('*', '' + index);
74
+ this.debug('Seek keyedMember', fsCollection, '#', memberId);
75
+ let docRef = FirestoreDocRef(Syncro.firestore, fsCollection, memberId);
76
+ let doc = await FirestoreGetDoc(docRef);
77
+ if (doc.exists()) { // Found a matching entry
78
+ // Expand member lookup with the new member by its numeric index
79
+ await this.keyedMembersExpand(index);
80
+ // Queue up next member fetcher
81
+ setTimeout(() => seekMember(index + 1));
82
+ }
83
+ else { // Likely reached end of possible members
84
+ resolve();
85
+ }
86
+ };
87
+ seekMember(0); // Look for first member
88
+ }))
89
+ .then(async () => {
90
+ if (this.members.length > 0)
91
+ return;
92
+ // Create at least one member in the registry
93
+ await this.keyedMembersExpand(0);
94
+ this.debug('Populate initial SyncroKeyed state');
95
+ // Extract base data + add document and return new hook
96
+ const entityKey = entity;
97
+ if (!SyncroEntities[entityKey])
98
+ throw new Error(`Unknown Sync entity "${entity}"`);
99
+ // Go fetch the initial state object
100
+ let state = await SyncroEntities[entityKey].initState({
101
+ supabasey: Syncro.supabasey,
102
+ id, relation,
103
+ });
104
+ await this.keyedAssign(state);
105
+ })
106
+ .then(() => {
107
+ let reactive = this.getReactive(this.proxy());
108
+ // Assuming this.value should hold the reactive proxy
109
+ // If this.value is inherited and has a specific type, this might need adjustment
110
+ this.value = reactive.doc;
111
+ })
112
+ .then(() => this);
113
+ }
114
+ /**
115
+ * Return a Proxy which will map setter/getter actions to their correct member
116
+ *
117
+ * @returns {Proxy} A proxy of all combined members
118
+ */
119
+ proxy() {
120
+ return new Proxy(this, {
121
+ // Return the full list of keys
122
+ ownKeys(target) {
123
+ return target.members.flatMap(m => Object.keys(m.value || {}));
124
+ },
125
+ // Return if we have a lookup key
126
+ has(target, prop) {
127
+ // Ensure m.value exists before checking property
128
+ return target.members.some(m => m.value && prop in m.value);
129
+ },
130
+ // Scope through members until we get a hit on the key
131
+ get(target, prop) {
132
+ let targetMember = target.members.find(m => m.value && prop in m.value);
133
+ // Access value via targetMember.value if found
134
+ return targetMember ? targetMember.value[prop] : undefined;
135
+ },
136
+ // Set the member key if one already exists, otherwise overflow onto the next member
137
+ set(target, prop, value) {
138
+ let targetMember = target.members.find(m => m.value && prop in m.value);
139
+ if (targetMember && targetMember.value) {
140
+ targetMember.value[prop] = value;
141
+ }
142
+ else {
143
+ // Assuming keyedSet handles adding the value appropriately
144
+ target.keyedSet(prop, value); // Cast prop to string if keyedSet expects string
145
+ }
146
+ return true; // Proxy set must return boolean
147
+ },
148
+ // Remove a key
149
+ deleteProperty(target, prop) {
150
+ let targetMember = target.members.find(m => m.value && prop in m.value);
151
+ if (targetMember && targetMember.value) {
152
+ delete targetMember.value[prop];
153
+ return true; // Indicate success
154
+ }
155
+ return false; // Indicate key not found or failure
156
+ },
157
+ });
158
+ }
159
+ /**
160
+ * Flush all member states
161
+ *
162
+ * @param {Object} [options] Additional options to mutate behaviour
163
+ * @param {Boolean} [options.destroy=false] Instruct the server to also dispose of the Syncro state
164
+ *
165
+ * @returns {Promise} A promise which resolves when the operation has completed
166
+ */
167
+ async flush(options) {
168
+ let settings = {
169
+ destroy: false,
170
+ ...options,
171
+ };
172
+ await Promise.all(this.members.map(member => member.flush({
173
+ destroy: settings.destroy,
174
+ })));
175
+ if (settings.destroy)
176
+ await this.destroy();
177
+ return; // Return void to match signature
178
+ }
179
+ /**
180
+ * Set a given key against the next available member
181
+ * This will either pick the next available member with keys below `config.maxKeys` or extend the member array and append to it
182
+ *
183
+ * @param {String} key The key to set
184
+ * @param {*} value The value to set
185
+ *
186
+ * @returns {Promise<*>} A promise which resolves when the operation has completed with the set value
187
+ */
188
+ async keyedSet(key, value) {
189
+ let candidateMember = this.members.find(m => m.value && Object.keys(m.value).length < this.keyedConfig.maxKeys);
190
+ if (candidateMember?.value) {
191
+ candidateMember.value[key] = value;
192
+ return value;
193
+ }
194
+ else { // No candidate - need to expand then set
195
+ // Extend members
196
+ await this.keyedMembersExpand(); // Call without index to append
197
+ // Get the newly added member
198
+ let newMember = this.members.at(-1);
199
+ if (!newMember || !newMember.value) {
200
+ throw new Error('Failed to expand members or new member has no value object');
201
+ }
202
+ // Sanity check (check the new member's value)
203
+ if (Object.keys(newMember.value).length >= this.keyedConfig.maxKeys) {
204
+ throw new Error(`Need to append key "${key}" but newly added member (offset #${this.members.length - 1}) has size of ${Object.keys(newMember.value).length}, exceeding maxKeys ${this.keyedConfig.maxKeys}`);
205
+ }
206
+ newMember.value[key] = value;
207
+ return value;
208
+ }
209
+ }
210
+ /**
211
+ * Assign an entire in-memory object to members
212
+ * This can be thought of as the optimized equivelent of Object.assign()
213
+ * Use this when merging large objects as it can make optimizations
214
+ *
215
+ * @param {Object} state The value to merge
216
+ */
217
+ async keyedAssign(state) {
218
+ // Can we assume we have a blank state - this speeds up existing key checks significantly
219
+ // Ensure members[0] and its value exist
220
+ let isBlank = this.members.length === 1 && this.members[0]?.value && Object.keys(this.members[0].value).length === 0;
221
+ if (isBlank) {
222
+ let chunks = chunk(Object.entries(state), this.keyedConfig.maxKeys)
223
+ .map(chunk => Object.fromEntries(chunk));
224
+ await Promise.all(chunks.map(async (chunk, chunkIndex) => {
225
+ this.debug(`Assign chunk #${chunkIndex} content`, { chunk });
226
+ // Create chunk document if its missing
227
+ if (!this.members[chunkIndex])
228
+ await this.keyedMembersExpand(chunkIndex);
229
+ // Ensure the member exists and has setFirestoreState method
230
+ const member = this.members[chunkIndex];
231
+ if (member && typeof member.setFirestoreState === 'function') {
232
+ // Populate its state - Cast to any temporarily if setFirestoreState is not public/recognized
233
+ await member.setFirestoreState(chunk, { method: 'set' });
234
+ }
235
+ else {
236
+ console.warn(`Member at index ${chunkIndex} is missing or does not have setFirestoreState`);
237
+ }
238
+ }));
239
+ }
240
+ else { // Non-blank - call keyedSet() on each key of state, merging slowly
241
+ // Replace Array.fromAsync with a standard loop
242
+ for (const [key, val] of Object.entries(state)) {
243
+ await this.keyedSet(key, val);
244
+ }
245
+ }
246
+ }
247
+ /**
248
+ * Extend the member pool by one member
249
+ *
250
+ * @param {Number} [index] The index to use when expanding, if omitted the next index offset is used
251
+ * @returns {Promise} A promise which resolves when the operation has completed
252
+ */
253
+ async keyedMembersExpand(index) {
254
+ index = index ?? this.members.length; // Use provided index or next available slot
255
+ if (this.members[index]) {
256
+ // If member already exists (e.g., during initial seek), just ensure it's mounted.
257
+ // If it was called intentionally with an existing index, maybe log a warning or skip.
258
+ this.debug(`keyedMembersExpand called for existing index ${index}, ensuring mounted.`);
259
+ if (!this.members[index].value) { // If it exists but isn't mounted somehow
260
+ await this.members[index].mount({ initialState: {} });
261
+ }
262
+ return; // Exit if member already exists
263
+ }
264
+ let syncroPath = this.keyedPath.getKey(this.path, index);
265
+ // Pass empty options object {} or specify allowAsterisk: false if needed
266
+ let { fsCollection, fsId } = Syncro.pathSplit(syncroPath, {});
267
+ this.debug('Expand SyncroKeyed size to index=', index);
268
+ // Create a new Syncro member, inheriteing some details from this parent item
269
+ let syncro = new Syncro(`${fsCollection}::${fsId}`, {
270
+ debug: this.debug,
271
+ getReactive: this.getReactive,
272
+ });
273
+ // Wait for mount to complete
274
+ await syncro.mount({
275
+ initialState: {}, // Force intital state to empty object so we don't get stuck in a loop
276
+ });
277
+ // Insert at the correct index if specified, otherwise push
278
+ if (index < this.members.length) {
279
+ this.members.splice(index, 0, syncro);
280
+ }
281
+ else {
282
+ this.members.push(syncro);
283
+ }
284
+ }
285
+ }
286
+ //# sourceMappingURL=keyed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyed.js","sourceRoot":"","sources":["../../../lib/syncro/keyed.ts"],"names":[],"mappings":"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"}