@iebh/tera-fy 1.0.16 → 1.0.18
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/README.md +3 -2
- package/api.md +333 -188
- package/dist/plugin.vue2.es2019.js +1 -1
- package/dist/plugin.vue2.es2019.js.map +3 -3
- package/dist/terafy.es2019.js +2 -2
- package/dist/terafy.es2019.js.map +3 -3
- package/dist/terafy.js +2 -2
- package/dist/terafy.js.map +3 -3
- package/hints.md +26 -0
- package/lib/terafy.client.js +149 -18
- package/lib/terafy.server.js +415 -54
- package/package.json +10 -11
- package/plugins/vue2.js +68 -0
- package/utils/pDefer.js +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iebh/tera-fy",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "TERA website worker",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "esbuild --platform=browser --format=esm --bundle lib/terafy.client.js --outfile=dist/terafy.js --minify --sourcemap --serve --servedir=.",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"build:plugins-vue2:es2019": "esbuild --platform=browser --format=esm --target=es2019 --bundle plugins/vue2.js --outfile=dist/plugin.vue2.es2019.js --minify --sourcemap",
|
|
11
11
|
"build:docs:api": "documentation build lib/terafy.client.js --format html --config documentation.yml --output docs/",
|
|
12
12
|
"build:docs:markdown": "documentation build lib/terafy.client.js --format md --markdown-toc --output api.md",
|
|
13
|
+
"watch": "nodemon --watch lib/terafy.client.js --exec npm run build",
|
|
13
14
|
"lint": "eslint ."
|
|
14
15
|
},
|
|
15
16
|
"type": "module",
|
|
@@ -62,21 +63,23 @@
|
|
|
62
63
|
"engines": {
|
|
63
64
|
"node": ">=18"
|
|
64
65
|
},
|
|
65
|
-
"
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"just-diff": "^6.0.2",
|
|
66
68
|
"lodash-es": "^4.17.21",
|
|
69
|
+
"mitt": "^3.0.1",
|
|
67
70
|
"nanoid": "^5.0.2"
|
|
68
71
|
},
|
|
69
|
-
"optionalDependencies": {
|
|
70
|
-
"just-diff": "^6.0.2",
|
|
71
|
-
"just-diff-apply": "^5.5.0",
|
|
72
|
-
"vue": "^3.3.7"
|
|
73
|
-
},
|
|
74
72
|
"devDependencies": {
|
|
75
73
|
"@momsfriendlydevco/eslint-config": "^1.0.7",
|
|
76
74
|
"concurrently": "^8.2.2",
|
|
77
75
|
"documentation": "^14.0.2",
|
|
78
76
|
"esbuild": "^0.19.5"
|
|
79
77
|
},
|
|
78
|
+
"optionalDependencies": {
|
|
79
|
+
"@iebh/reflib": "^2.2.2",
|
|
80
|
+
"just-diff-apply": "^5.5.0",
|
|
81
|
+
"vue": "^3.3.7"
|
|
82
|
+
},
|
|
80
83
|
"eslintConfig": {
|
|
81
84
|
"extends": "@momsfriendlydevco",
|
|
82
85
|
"env": {
|
|
@@ -87,9 +90,5 @@
|
|
|
87
90
|
"ecmaVersion": 13,
|
|
88
91
|
"sourceType": "module"
|
|
89
92
|
}
|
|
90
|
-
},
|
|
91
|
-
"dependencies": {
|
|
92
|
-
"@momsfriendlydevco/supabase-reactive": "^1.0.7",
|
|
93
|
-
"mitt": "^3.0.1"
|
|
94
93
|
}
|
|
95
94
|
}
|
package/plugins/vue2.js
CHANGED
|
@@ -151,6 +151,7 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
151
151
|
* @param {Object} options.app Root level Vue app to bind against
|
|
152
152
|
* @param {Vue} options.Vue Vue@2 instance to bind against
|
|
153
153
|
* @param {String} [options.globalName='$tera'] Global property to allocate this service as within Vue2
|
|
154
|
+
* @param {Boolean} [options.requireProject=true] Automatically call requireProject() prior to any operation
|
|
154
155
|
* @param {Boolean} [options.subscribeState=true] Setup `vm.$tera.state` as a live binding on init
|
|
155
156
|
* @param {Boolean} [options.subscribeList=true] Setup `vm.$tera.projects` as a list of accesible projects on init
|
|
156
157
|
* @param {Objecct} [options.stateOptions] Options passed to `bindProjectState()` when setting up the main state
|
|
@@ -162,6 +163,7 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
162
163
|
app: null,
|
|
163
164
|
Vue: null,
|
|
164
165
|
globalName: '$tera',
|
|
166
|
+
requireProject: true,
|
|
165
167
|
subscribeState: true,
|
|
166
168
|
subscribeProjects: true,
|
|
167
169
|
stateOptions: {
|
|
@@ -190,6 +192,7 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
190
192
|
|
|
191
193
|
// this.statePromisable becomes the promise we are waiting on to resolve
|
|
192
194
|
return Promise.resolve()
|
|
195
|
+
.then(()=> settings.requireProject && this.requireProject())
|
|
193
196
|
.then(()=> Promise.all([
|
|
194
197
|
// Bind available project and wait on it
|
|
195
198
|
settings.subscribeState && this.bindProjectState({
|
|
@@ -205,4 +208,69 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
205
208
|
.then(()=> this.debug('INFO', 'Loaded projects', this.projects)),
|
|
206
209
|
]))
|
|
207
210
|
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Override the regular _pathSet() handler so that it stays as a Vue observable
|
|
215
|
+
* This function will correctly populate any missing entities, calling vm.$set on each traversal of the path This is mainly to fix the issue where Vue can't see changes to objects if a key is added or removed
|
|
216
|
+
* Passing undefined as a value removes the key (unless removeUndefined is set to false)
|
|
217
|
+
*
|
|
218
|
+
* @override
|
|
219
|
+
* @param {Object} [target] The target to set the path of, if omitted the `vm` object is used as the base for traversal
|
|
220
|
+
* @param {string|array} path The path to set within the target / vm
|
|
221
|
+
* @param {*} value The value to set
|
|
222
|
+
* @param {Object} [options] Additional options
|
|
223
|
+
* @param {boolean} [options.arrayNumeric=true] Process numeric path segments as arrays
|
|
224
|
+
* @param {boolean} [options.removeUndefined=true] If undefined is specified as a value the key is removed instead of being set
|
|
225
|
+
* @param {boolean} [options.debug=false] Also print out debugging information when setting the value
|
|
226
|
+
* @returns {Object} The set value, like $set()
|
|
227
|
+
*
|
|
228
|
+
* @example Set a deeply nested path within a target object
|
|
229
|
+
* vm.$setPath(this, 'foo.bar.baz', 123); // this.$data.foo.bar.baz = 123
|
|
230
|
+
*
|
|
231
|
+
* @example Set a deeply nested path, with arrays, assuming VM as the root node
|
|
232
|
+
* vm.$setPath('foo.1.bar', 123); // vm.$data.foo = [{bar: 123}]
|
|
233
|
+
*/
|
|
234
|
+
_pathSet(target, path, value, options) {
|
|
235
|
+
// Sanity checks {{{
|
|
236
|
+
if (typeof target != 'object') throw new Error('Cannot use _pathSet on non-object target');
|
|
237
|
+
// }}}
|
|
238
|
+
|
|
239
|
+
let settings = {
|
|
240
|
+
arrayNumeric: true,
|
|
241
|
+
debug: false,
|
|
242
|
+
removeUndefined: true,
|
|
243
|
+
...options,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
if (settings.debug) console.log('[_pathSet]', path, '=', value, {target, options});
|
|
247
|
+
|
|
248
|
+
let node = target;
|
|
249
|
+
if (!path) throw new Error('Cannot _pathSet with undefined path');
|
|
250
|
+
(typeof path == 'string' ? path.split('.') : path).some((chunk, chunkIndex, chunks) => {
|
|
251
|
+
if (chunkIndex == chunks.length - 1) { // Leaf node
|
|
252
|
+
if (settings.removeUndefined && value === undefined) {
|
|
253
|
+
this.Vue.$delete(node, chunk);
|
|
254
|
+
} else {
|
|
255
|
+
this.Vue.set(node, chunk, value);
|
|
256
|
+
}
|
|
257
|
+
} else if (node[chunk] === undefined) { // This chunk (and all following chunks) does't exist - populate from here
|
|
258
|
+
chunks.slice(chunkIndex, chunks.length - 1).forEach(chunk => {
|
|
259
|
+
if (settings.arrayNumeric && isFinite(chunk)) {
|
|
260
|
+
this.Vue.set(node, chunk, []);
|
|
261
|
+
} else {
|
|
262
|
+
this.Vue.set(node, chunk, {});
|
|
263
|
+
}
|
|
264
|
+
node = node[chunk];
|
|
265
|
+
});
|
|
266
|
+
this.Vue.set(node, chunks[chunks.length - 1], value);
|
|
267
|
+
return true;
|
|
268
|
+
} else {
|
|
269
|
+
node = node[chunk];
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
208
276
|
}
|
package/utils/pDefer.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a defer object which represents a promise object which can resolve in the future - but without enclosing a function
|
|
3
|
+
* The defer object has the keys {promise, resolve(), reject()}
|
|
4
|
+
* @returns {Defer} A defered promise
|
|
5
|
+
*/
|
|
6
|
+
export default function() {
|
|
7
|
+
var deferred = {};
|
|
8
|
+
|
|
9
|
+
deferred.promise = new Promise((resolve, reject) => {
|
|
10
|
+
deferred.resolve = resolve;
|
|
11
|
+
deferred.reject = reject;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return deferred;
|
|
15
|
+
}
|