@iebh/tera-fy 2.3.10 → 2.3.12

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 (82) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/api.md +8 -11
  3. package/dist/plugin.vue2.es2019.js +28 -27
  4. package/dist/terafy.bootstrapper.es2019.js +2 -2
  5. package/dist/terafy.bootstrapper.js +2 -2
  6. package/dist/terafy.es2019.js +5 -5
  7. package/dist/terafy.js +5 -5
  8. package/eslint.config.js +4 -66
  9. package/lib/{projectFile.ts → projectFile.js} +52 -76
  10. package/lib/syncro/{entities.ts → entities.js} +14 -83
  11. package/lib/syncro/{keyed.ts → keyed.js} +46 -68
  12. package/lib/syncro/{syncro.ts → syncro.js} +104 -136
  13. package/lib/{terafy.bootstrapper.ts → terafy.bootstrapper.js} +20 -30
  14. package/lib/{terafy.client.ts → terafy.client.js} +85 -84
  15. package/lib/{terafy.proxy.ts → terafy.proxy.js} +12 -26
  16. package/lib/{terafy.server.ts → terafy.server.js} +204 -229
  17. package/package.json +20 -39
  18. package/plugins/{base.ts → base.js} +3 -5
  19. package/plugins/{firebase.ts → firebase.js} +22 -21
  20. package/plugins/{vite.ts → vite.js} +3 -3
  21. package/plugins/{vue2.ts → vue2.js} +8 -10
  22. package/plugins/{vue3.ts → vue3.js} +7 -10
  23. package/utils/mixin.js +15 -0
  24. package/utils/{pathTools.ts → pathTools.js} +8 -9
  25. package/widgets/tera-file-select.vue +1 -1
  26. package/dist/lib/projectFile.d.ts +0 -190
  27. package/dist/lib/projectFile.js +0 -305
  28. package/dist/lib/projectFile.js.map +0 -1
  29. package/dist/lib/syncro/entities.d.ts +0 -34
  30. package/dist/lib/syncro/entities.js +0 -212
  31. package/dist/lib/syncro/entities.js.map +0 -1
  32. package/dist/lib/syncro/keyed (Rhino's conflicted copy 2026-05-10).js +0 -287
  33. package/dist/lib/syncro/keyed.d.ts +0 -95
  34. package/dist/lib/syncro/keyed.js +0 -288
  35. package/dist/lib/syncro/keyed.js (Rhino's conflicted copy 2026-05-10).map +0 -1
  36. package/dist/lib/syncro/keyed.js.map +0 -1
  37. package/dist/lib/syncro/syncro (Rhino's conflicted copy 2026-05-10).js +0 -765
  38. package/dist/lib/syncro/syncro.d (Rhino's conflicted copy 2026-05-10).ts +0 -336
  39. package/dist/lib/syncro/syncro.d.ts +0 -343
  40. package/dist/lib/syncro/syncro.js +0 -771
  41. package/dist/lib/syncro/syncro.js (Rhino's conflicted copy 2026-05-10).map +0 -1
  42. package/dist/lib/syncro/syncro.js.map +0 -1
  43. package/dist/lib/terafy.bootstrapper.d.ts +0 -42
  44. package/dist/lib/terafy.bootstrapper.js +0 -129
  45. package/dist/lib/terafy.bootstrapper.js.map +0 -1
  46. package/dist/lib/terafy.client.d.ts +0 -555
  47. package/dist/lib/terafy.client.js +0 -1153
  48. package/dist/lib/terafy.client.js.map +0 -1
  49. package/dist/lib/terafy.proxy.d.ts +0 -66
  50. package/dist/lib/terafy.proxy.js +0 -130
  51. package/dist/lib/terafy.proxy.js.map +0 -1
  52. package/dist/lib/terafy.server.d.ts +0 -697
  53. package/dist/lib/terafy.server.js +0 -2062
  54. package/dist/lib/terafy.server.js.map +0 -1
  55. package/dist/plugin.vue2.es2019 (Rhino's conflicted copy 2026-05-10).js +0 -1271
  56. package/dist/plugins/base.d.ts +0 -20
  57. package/dist/plugins/base.js +0 -22
  58. package/dist/plugins/base.js.map +0 -1
  59. package/dist/plugins/firebase.d.ts +0 -62
  60. package/dist/plugins/firebase.js +0 -123
  61. package/dist/plugins/firebase.js.map +0 -1
  62. package/dist/plugins/vite.d.ts +0 -12
  63. package/dist/plugins/vite.js +0 -22
  64. package/dist/plugins/vite.js.map +0 -1
  65. package/dist/plugins/vue2.d.ts +0 -67
  66. package/dist/plugins/vue2.js +0 -104
  67. package/dist/plugins/vue2.js.map +0 -1
  68. package/dist/plugins/vue3.d.ts +0 -63
  69. package/dist/plugins/vue3.js +0 -93
  70. package/dist/plugins/vue3.js.map +0 -1
  71. package/dist/utils/mixin.d.ts +0 -11
  72. package/dist/utils/mixin.js +0 -15
  73. package/dist/utils/mixin.js.map +0 -1
  74. package/dist/utils/pDefer.d.ts +0 -16
  75. package/dist/utils/pDefer.js +0 -19
  76. package/dist/utils/pDefer.js.map +0 -1
  77. package/dist/utils/pathTools.d.ts +0 -70
  78. package/dist/utils/pathTools.js +0 -120
  79. package/dist/utils/pathTools.js.map +0 -1
  80. package/tsconfig.json +0 -30
  81. package/utils/mixin.ts +0 -18
  82. package/utils/pDefer.ts +0 -27
@@ -1,212 +0,0 @@
1
- /* eslint-disable jsdoc/reject-function-type, no-unused-vars */
2
- // @ts-expect-error TODO: Remove when reflib gets declaration file
3
- import Reflib from '@iebh/reflib';
4
- import { v4 as uuid4 } from 'uuid';
5
- import { nanoid } from 'nanoid';
6
- /**
7
- * Entities we support Syncro paths for, each should correspond directly with a Firebase/Firestore collection name
8
- *
9
- * @type {Object} An object lookup of entities
10
- *
11
- * @property {String} singular The singular noun for the item
12
- * @property {Function} initState Function called to initialize state when Firestore has no existing document. Called as `({HYPERDRIVE:PostgresSql, supabasey:BoundSupabaseyFunction, id:String, relation?:string})` and expected to return the initial data object state
13
- * @property {Function} flushState Function called to flush state from Firebase to Postgres. Called the same as `initState` + `{state:Object}`
14
- */
15
- const syncroConfig = {
16
- institutes: {
17
- singular: 'institute',
18
- async initState({ HYPERDRIVE, id }) {
19
- let rows = await HYPERDRIVE `
20
- SELECT data
21
- FROM institutes
22
- WHERE id = ${id}
23
- LIMIT 1
24
- `;
25
- if (rows.length > 0) {
26
- return rows[0].data; // institute is valid and already exists
27
- }
28
- else {
29
- throw new Error(`Syncro institute "${id}" not found`);
30
- }
31
- },
32
- flushState({ HYPERDRIVE, state, id }) {
33
- return HYPERDRIVE `
34
- SELECT syncro_merge_data(
35
- table_name => 'institutes',
36
- entity_id => ${id}::UUID,
37
- new_data => ${HYPERDRIVE.json(state)}::JSONB
38
- )
39
- `;
40
- },
41
- }, // }}}
42
- projects: {
43
- singular: 'project',
44
- async initState({ HYPERDRIVE, supabasey, id }) {
45
- let rows = await HYPERDRIVE `
46
- SELECT data
47
- FROM projects
48
- WHERE id = ${id}
49
- LIMIT 1
50
- `;
51
- if (rows.length == 0)
52
- throw new Error(`Syncro project "${id}" not found`);
53
- const data = rows[0].data;
54
- // MIGRATION - Move data.temp{} into Supabase files + add pointer to filename {{{
55
- if (data.temp // Project contains temp subkey
56
- && Object.values(data.temp).some((t) => typeof t == 'object') // Some of the temp keys are objects
57
- ) {
58
- console.log('[MIGRATION] tera-fy project v1 -> v2', data.temp);
59
- const tempObject = data.temp;
60
- await Promise.all(Object.entries(data.temp)
61
- .filter(([, branch]) => typeof branch == 'object')
62
- .map(([toolKey]) => {
63
- console.log(`[MIGRATION] Converting data.temp[${toolKey}]...`);
64
- const toolName = toolKey.split('-')[0];
65
- const fileName = `data-${toolName}-${nanoid()}.json`;
66
- console.log('[MIGRATION] Creating filename:', fileName);
67
- return Promise.resolve()
68
- .then(() => supabasey((supabase) => supabase // Split data.temp[toolKey] -> file {{{
69
- .storage
70
- .from('projects')
71
- .upload(`${id}/${fileName}`, new File([
72
- new Blob([
73
- JSON.stringify(tempObject[toolKey], null, '\t'),
74
- ], {
75
- type: 'application/json',
76
- }),
77
- ], fileName, {
78
- type: 'application/json',
79
- }), {
80
- cacheControl: '3600',
81
- upsert: true,
82
- }))) // }}}
83
- .then(() => tempObject[toolKey] = fileName) // Replace data.temp[toolKey] with new filename
84
- .catch(e => {
85
- console.warn('[MIGRATION] Failed to create file', fileName, '-', e);
86
- throw e;
87
- });
88
- }));
89
- } // }}}
90
- return data;
91
- },
92
- flushState({ HYPERDRIVE, state, fsId }) {
93
- return HYPERDRIVE `
94
- SELECT syncro_merge_data(
95
- table_name => 'projects',
96
- entity_id => ${fsId}::UUID,
97
- new_data => ${HYPERDRIVE.json(state)}::JSONB
98
- )
99
- `;
100
- },
101
- }, // }}}
102
- project_libraries: {
103
- singular: 'project library',
104
- async initState({ id, relation, supabasey }) {
105
- if (!relation || !/_\*$/.test(relation))
106
- throw new Error('Project library relation missing, path should resemble "project_library::${PROJECT}::${LIBRARY_FILE_ID}_*"');
107
- const fileId = relation.replace(/_\*$/, '');
108
- const files = await supabasey((supabase) => supabase
109
- .storage
110
- .from('projects')
111
- .list(id));
112
- const file = files?.find((f) => f.id == fileId);
113
- if (!file)
114
- return Promise.reject(`Invalid file ID "${fileId}"`);
115
- const blob = await supabasey((supabase) => supabase
116
- .storage
117
- .from('projects')
118
- .download(`${id}/${file.name}`));
119
- if (!blob)
120
- throw new Error('Failed to download file blob');
121
- const refs = await Reflib.uploadFile({
122
- file: new File([blob], file.name.replace(/^.*[/\\]/, '')),
123
- });
124
- return Object.fromEntries(refs // Transform Reflib Ref array into a keyed UUID object
125
- .map((ref) => [
126
- uuid4(), // TODO: This should really be using V5 with some-kind of namespacing but I can't get my head around the documentation - MC 2025-02-21
127
- ref, // The actual ref payload
128
- ]));
129
- },
130
- flushState() {
131
- throw new Error('Flushing project_libraries::* namespace is not yet supported');
132
- },
133
- }, // }}}
134
- project_namespaces: {
135
- singular: 'project namespace',
136
- async initState() {
137
- throw new Error('Updating project_namespaces is not yet supported');
138
- },
139
- async flushState() {
140
- throw new Error('Updating project_namespaces is not yet supported');
141
- },
142
- }, // }}}
143
- test: {
144
- singular: 'test',
145
- async initState({ HYPERDRIVE, id }) {
146
- let rows = await HYPERDRIVE `
147
- SELECT data
148
- FROM test
149
- WHERE id = ${id}
150
- LIMIT 1
151
- `;
152
- if (rows.length > 0) {
153
- return rows[0].data; // User is valid and already exists
154
- }
155
- else {
156
- throw new Error(`Syncro test "${id}" not found`);
157
- }
158
- },
159
- flushState({ HYPERDRIVE, state, fsId }) {
160
- return HYPERDRIVE `
161
- SELECT syncro_merge_data(
162
- table_name => 'test',
163
- entity_id => ${fsId}::UUID,
164
- new_data => ${HYPERDRIVE.json(state)}::JSONB
165
- )
166
- `;
167
- },
168
- }, // }}}
169
- users: {
170
- singular: 'user',
171
- async initState({ HYPERDRIVE, id }) {
172
- let rows = await HYPERDRIVE `
173
- SELECT data
174
- FROM users
175
- WHERE id = ${id}
176
- LIMIT 1
177
- `;
178
- if (rows.length > 0)
179
- return rows[0].data; // User is valid and already exists
180
- // User row doesn't already exist - this shouldn't happen if the user has correctly gone through the onboarding process
181
- // but... *shrugs*, who knows
182
- let newUser = await HYPERDRIVE `
183
- INSERT INTO users
184
- (
185
- id,
186
- data
187
- )
188
- VALUES (
189
- ${id},
190
- ${HYPERDRIVE.json({
191
- id,
192
- credits: 1000,
193
- })}::JSONB
194
- )
195
- `;
196
- if (!newUser?.length)
197
- throw new Error(`Failed to create new user "${id}"`);
198
- return newUser[0].data; // Return back the data that eventually got created - allowing for database triggers, default field values etc.
199
- },
200
- flushState({ HYPERDRIVE, state, fsId }) {
201
- return HYPERDRIVE `
202
- SELECT syncro_merge_data(
203
- table_name => 'users',
204
- entity_id => ${fsId}::UUID,
205
- new_data => ${HYPERDRIVE.json(state)}::JSONB
206
- )
207
- `;
208
- },
209
- }, // }}}
210
- };
211
- export default syncroConfig;
212
- //# sourceMappingURL=entities.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entities.js","sourceRoot":"","sources":["../../../lib/syncro/entities.ts"],"names":[],"mappings":"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"}
@@ -1,287 +0,0 @@
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 (potentially very large) single Syncro object by splitting it across 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: 2,
21
- };
22
- /**
23
- * Various storage about keyed path
24
- */
25
- keyedPath = {
26
- getKey(path, index) {
27
- return path + '_' + index;
28
- },
29
- };
30
- /**
31
- * Member Syncros which form part of this meta Syncro
32
- *
33
- * @type {Array<Syncro>}
34
- */
35
- members = [];
36
- /**
37
- * Instance constructor
38
- *
39
- * @param {String} path Mount path for the Syncro. Should be in the form `${ENTITY}::${ID}(::${RELATION})?_*` (must contain a '*' operator)
40
- * @param {Object} [options] Additional instance setters (mutates instance directly)
41
- */
42
- constructor(path, options) {
43
- super(path, options);
44
- if (!/\*/.test(path))
45
- throw new Error('SyncroKeyed paths must contain at least one asterisk as an object pagination indicator');
46
- const { 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
- const { 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
- const seekMember = async (index) => {
73
- const memberId = fsId.replace('*', '' + index);
74
- this.debug('Seek keyedMember', fsCollection, '#', memberId);
75
- const docRef = FirestoreDocRef(Syncro.firestore, fsCollection, memberId);
76
- const 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
- const state = await SyncroEntities[entityKey].initState({
101
- supabasey: Syncro.supabasey,
102
- id, relation,
103
- });
104
- await this.keyedAssign(state);
105
- })
106
- .then(() => {
107
- const 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
- const 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
- const 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
- const 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
- const 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
- const 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
- // eslint-disable-next-line unicorn/prefer-at
199
- const newMember = this.members[this.members.length - 1];
200
- if (!newMember || !newMember.value) {
201
- throw new Error('Failed to expand members or new member has no value object');
202
- }
203
- // Sanity check (check the new member's value)
204
- if (Object.keys(newMember.value).length >= this.keyedConfig.maxKeys) {
205
- 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}`);
206
- }
207
- newMember.value[key] = value;
208
- return value;
209
- }
210
- }
211
- /**
212
- * Assign an entire in-memory object to members
213
- * This can be thought of as the optimized equivalent of Object.assign()
214
- * Use this when merging large objects as it can make optimizations
215
- *
216
- * @param {Object} state The value to merge
217
- */
218
- async keyedAssign(state) {
219
- // Can we assume we have a blank state - this speeds up existing key checks significantly
220
- // Ensure members[0] and its value exist
221
- const isBlank = this.members.length === 1 && this.members[0]?.value && Object.keys(this.members[0].value).length === 0;
222
- if (isBlank) {
223
- const chunks = chunk(Object.entries(state), this.keyedConfig.maxKeys)
224
- .map(chunk => Object.fromEntries(chunk));
225
- await Promise.all(chunks.map(async (chunk, chunkIndex) => {
226
- this.debug(`Assign chunk #${chunkIndex} content`, { chunk });
227
- // Create chunk document if its missing
228
- if (!this.members[chunkIndex])
229
- await this.keyedMembersExpand(chunkIndex);
230
- // Ensure the member exists and has setFirestoreState method
231
- const member = this.members[chunkIndex];
232
- if (member && typeof member.setFirestoreState === 'function') {
233
- // Populate its state - Cast to any temporarily if setFirestoreState is not public/recognized
234
- await member.setFirestoreState(chunk, { method: 'set' });
235
- }
236
- else {
237
- console.warn(`Member at index ${chunkIndex} is missing or does not have setFirestoreState`);
238
- }
239
- }));
240
- }
241
- else { // Non-blank - call keyedSet() on each key of state, merging slowly
242
- // Replace Array.fromAsync with a standard loop
243
- for (const [key, val] of Object.entries(state)) {
244
- await this.keyedSet(key, val);
245
- }
246
- }
247
- }
248
- /**
249
- * Extend the member pool by one member
250
- *
251
- * @param {Number} [index] The index to use when expanding, if omitted the next index offset is used
252
- * @returns {Promise} A promise which resolves when the operation has completed
253
- */
254
- async keyedMembersExpand(index) {
255
- index = index ?? this.members.length; // Use provided index or next available slot
256
- if (this.members[index]) {
257
- // If member already exists (e.g., during initial seek), just ensure it's mounted.
258
- // If it was called intentionally with an existing index, maybe log a warning or skip.
259
- this.debug(`keyedMembersExpand called for existing index ${index}, ensuring mounted.`);
260
- if (!this.members[index].value) { // If it exists but isn't mounted somehow
261
- await this.members[index].mount({ initialState: {} });
262
- }
263
- return; // Exit if member already exists
264
- }
265
- const syncroPath = this.keyedPath.getKey(this.path, index);
266
- // Pass empty options object {} or specify allowAsterisk: false if needed
267
- const { fsCollection, fsId } = Syncro.pathSplit(syncroPath, {});
268
- this.debug('Expand SyncroKeyed size to index=', index);
269
- // Create a new Syncro member, inheriteing some details from this parent item
270
- const syncro = new Syncro(`${fsCollection}::${fsId}`, {
271
- debug: this.debug,
272
- getReactive: this.getReactive,
273
- });
274
- // Wait for mount to complete
275
- await syncro.mount({
276
- initialState: {}, // Force initial state to empty object so we don't get stuck in a loop
277
- });
278
- // Insert at the correct index if specified, otherwise push
279
- if (index < this.members.length) {
280
- this.members.splice(index, 0, syncro);
281
- }
282
- else {
283
- this.members.push(syncro);
284
- }
285
- }
286
- }
287
- //# sourceMappingURL=keyed.js.map
@@ -1,95 +0,0 @@
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 (potentially very large) single Syncro object by splitting it across 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 equivalent 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 {};