@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iebh/tera-fy",
3
- "version": "1.0.16",
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
- "peerDependencies": {
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
  }
@@ -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
+ }