@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
@@ -1,232 +0,0 @@
1
- import Reflib from '@iebh/reflib';
2
- import {v4 as uuid4} from 'uuid';
3
- import {nanoid} from 'nanoid';
4
-
5
- /**
6
- * Entities we support Syncro paths for, each should correspond directly with a Firebase/Firestore collection name
7
- *
8
- * @type {Object} An object lookup of entities
9
- *
10
- * @property {String} singular The singular noun for the item
11
- * @property {Function} initState Function called to initialize state when Firestore has no existing document. Called as `({supabase:Supabasey, entity:String, id:String, relation?:string})` and expected to return the initial data object state
12
- * @property {Function} flushState Function called to flush state from Firebase to Supabase. Called the same as `initState` + `{state:Object}`
13
- */
14
- export default {
15
- projects: { // {{{
16
- singular: 'project',
17
- async initState({supabase, id}) {
18
- let data = await supabase
19
- .from('projects')
20
- .select('data')
21
- .maybeSingle()
22
- .eq('id', id)
23
- if (!data) throw new Error(`Syncro project "${id}" not found`);
24
- data = data.data;
25
-
26
- // MIGRATION - Move data.temp{} into Supabase files + add pointer to filename {{{
27
- if (
28
- data.temp // Project contains no temp subkey
29
- && Object.values(data.temp).some(t => typeof t == 'object') // Some of the temp keys are objects
30
- ) {
31
- console.log('[MIGRATION] tera-fy project v1 -> v2', data.temp);
32
-
33
- await Promise.all(
34
- Object.entries(data.temp)
35
- .filter(([, branch]) => typeof branch == 'object')
36
- .map(([toolKey, ]) => {
37
- console.log(`[MIGRATION] Converting data.temp[${toolKey}]...`);
38
-
39
- const toolName = toolKey.split('-')[0];
40
- const fileName = `data-${toolName}-${nanoid()}.json`;
41
- console.log('[MIGRATION] Creating filename:', fileName);
42
-
43
- return Promise.resolve()
44
- .then(()=> supabase // Split data.temp[toolKey] -> file {{{
45
- .storage
46
- .from('projects')
47
- .upload(
48
- `${id}/${fileName}`,
49
- new File(
50
- [
51
- new Blob(
52
- [
53
- JSON.stringify(data.temp[toolKey], null, '\t'),
54
- ],
55
- {
56
- type: 'application/json',
57
- },
58
- ),
59
- ],
60
- fileName,
61
- {
62
- type: 'application/json',
63
- },
64
- ),
65
- {
66
- cacheControl: '3600',
67
- upsert: true,
68
- },
69
- )
70
- ) // }}}
71
- .then(()=> data.temp[toolKey] = fileName) // Replace data.temp[toolKey] with new filename
72
- .catch(e => {
73
- console.warn('[MIGRATION] Failed to create file', fileName, '-', e);
74
- throw e;
75
- })
76
-
77
- })
78
- );
79
- } // }}}
80
-
81
- return data;
82
- },
83
- flushState({supabase, state, fsId}) {
84
- return supabase.rpc('syncro_merge_data', {
85
- table_name: 'projects',
86
- entity_id: fsId,
87
- new_data: state,
88
- })
89
- },
90
- }, // }}}
91
- project_libraries: { // {{{
92
- singular: 'project library',
93
- initState({supabase, id, relation}) {
94
- if (!relation || !/_\*$/.test(relation)) throw new Error('Project library relation missing, path should resemble "project_library::${PROJECT}::${LIBRARY_FILE_ID}_*"');
95
-
96
- let fileId = relation.replace(/_\*$/, '');
97
-
98
- return Promise.resolve()
99
- .then(()=> supabase.storage
100
- .from('projects')
101
- .list(id)
102
- )
103
- .then(files => files.find(f => f.id == fileId))
104
- .then(file => file || Promise.reject(`Invalid file ID "${fileId}"`))
105
- .then(file => supabase.storage
106
- .from('projects')
107
- .download(`${id}/${file.name}`)
108
- .then(({ data: blob, error }) => {
109
- if (error) throw error;
110
- if (!blob) throw new Error('Failed to download file blob');
111
- return {blob, file}
112
- })
113
- )
114
- .then(({blob, file}) => Reflib.uploadFile({
115
- file: new File(
116
- [blob],
117
- file.name.replace(/^.*[/\\]/, ''), // Extract basename from original file name
118
- ),
119
- }))
120
- .then(refs => Object.fromEntries(refs // Transform Reflib Ref array into a keyed UUID object
121
- .map(ref => [ // Construct Object.fromEntries() compatible object [key, val] tuple
122
- 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
123
- ref, // The actual ref payload
124
- ])
125
- ))
126
- },
127
- flushState() {
128
- throw new Error('Flushing project_libraries::* namespace is not yet supported');
129
- },
130
- }, // }}}
131
- project_namespaces: { // {{{
132
- singular: 'project namespace',
133
- async initState({supabase, id, relation}) {
134
- if (!relation) throw new Error('Project namespace relation missing, path should resemble "project_namespaces::${PROJECT}::${RELATION}"');
135
- let { data: rows, error: selectError } = await supabase
136
- .from('project_namespaces')
137
- .select('data')
138
- .eq('project', id)
139
- .eq('name', relation)
140
- .limit(1);
141
-
142
- if (selectError) throw selectError;
143
-
144
- if (rows && rows.length == 1) {
145
- return rows[0].data;
146
- } else {
147
- const { data: newItem, error: insertError } = await supabase
148
- .from('project_namespaces') // Doesn't exist - create it
149
- .insert({
150
- project: id,
151
- name: relation,
152
- data: {},
153
- })
154
- .select('data')
155
- .single(); // Assuming insert returns the single inserted row
156
-
157
- if (insertError) throw insertError;
158
- if (!newItem) throw new Error('Failed to create project namespace');
159
- return newItem.data;
160
- }
161
- },
162
- flushState({supabase, state, id, relation}) {
163
- return supabase
164
- .from('project_namespaces')
165
- .update({
166
- edited_at: new Date(),
167
- data: state,
168
- })
169
- .eq('project', id)
170
- .eq('name', relation)
171
- },
172
- }, // }}}
173
- test: { // {{{
174
- singular: 'test',
175
- async initState({supabase, id}) {
176
- const { data: rows, error } = await supabase
177
- .from('test')
178
- .select('data')
179
- .eq('id', id)
180
- .limit(1);
181
-
182
- if (error) throw error;
183
- if (!rows || rows.length !== 1) return Promise.reject(`Syncro test item "${id}" not found`);
184
- return rows[0].data;
185
- },
186
- flushState({supabase, state, fsId}) {
187
- return supabase.rpc('syncro_merge_data', {
188
- table_name: 'test',
189
- entity_id: fsId,
190
- new_data: state,
191
- })
192
- },
193
- }, // }}}
194
- users: { // {{{
195
- singular: 'user',
196
- async initState({supabase, id}) {
197
- const { data: user, error: selectError } = await supabase
198
- .from('users')
199
- .select('data')
200
- .eq('id', id)
201
- .maybeSingle();
202
-
203
- if (selectError) throw selectError;
204
-
205
- if (user) return user.data; // User is valid and already exists
206
-
207
- // User row doesn't already exist - need to create stub
208
- const { data: newUser, error: insertError } = await supabase
209
- .from('users')
210
- .insert({
211
- id,
212
- data: {
213
- id,
214
- credits: 1000,
215
- },
216
- })
217
- .select('data')
218
- .single(); // Assuming insert returns the single inserted row
219
-
220
- if (insertError) throw insertError;
221
- if (!newUser) throw new Error('Failed to create user');
222
- return newUser.data; // Return back the data that eventually got created - allowing for database triggers, default field values etc.
223
- },
224
- flushState({supabase, state, fsId}) {
225
- return supabase.rpc('syncro_merge_data', {
226
- table_name: 'users',
227
- entity_id: fsId,
228
- new_data: state,
229
- })
230
- },
231
- }, // }}}
232
- };