@iebh/tera-fy 1.12.0 → 1.13.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.
- package/CHANGELOG.md +14 -0
- package/api.md +295 -234
- package/dist/plugin.vue2.es2019.js +1 -1
- package/dist/terafy.es2019.js +2 -2
- package/dist/terafy.js +2 -2
- package/eslint.config.js +14 -0
- package/lib/terafy.client.js +86 -6
- package/lib/terafy.server.js +97 -1
- package/package.json +8 -18
package/lib/terafy.client.js
CHANGED
|
@@ -27,6 +27,7 @@ export default class TeraFy {
|
|
|
27
27
|
* @property {Array<String>} List of sandbox allowables for the embedded if in embed mode
|
|
28
28
|
* @property {Number} handshakeInterval Interval in milliseconds when sanning for a handshake
|
|
29
29
|
* @property {Number} handshakeTimeout Interval in milliseconds for when to give up trying to handshake
|
|
30
|
+
* @property {Array<String|Array<String>>} [debugPaths] List of paths (in either dotted or array notation) to enter debugging mode if a change is detected in dev mode e.g. `{debugPaths: ['foo.bar.baz']}`. This really slows down state writes so should only be used for debugging
|
|
30
31
|
*/
|
|
31
32
|
settings = {
|
|
32
33
|
devMode: true,
|
|
@@ -50,6 +51,7 @@ export default class TeraFy {
|
|
|
50
51
|
],
|
|
51
52
|
handshakeInterval: 1000, // ~1s
|
|
52
53
|
handshakeTimeout: 10000, // ~10s
|
|
54
|
+
debugPaths: null, // Transformed into a Array<String> (in Lodash dotted notation) on init()
|
|
53
55
|
};
|
|
54
56
|
|
|
55
57
|
|
|
@@ -108,7 +110,7 @@ export default class TeraFy {
|
|
|
108
110
|
'setProjectStateRefresh',
|
|
109
111
|
'saveProjectState',
|
|
110
112
|
'replaceProjectState',
|
|
111
|
-
'applyProjectStatePatch',
|
|
113
|
+
// 'applyProjectStatePatch', - Handled below (applies behaviour to watch for `settings.debugPaths`)
|
|
112
114
|
// For bindProjectState() - See individual plugins
|
|
113
115
|
|
|
114
116
|
// Project files
|
|
@@ -134,7 +136,10 @@ export default class TeraFy {
|
|
|
134
136
|
|
|
135
137
|
// UI
|
|
136
138
|
'uiAlert',
|
|
139
|
+
'uiConfirm',
|
|
137
140
|
'uiProgress',
|
|
141
|
+
'uiPrompt',
|
|
142
|
+
'uiTrhow',
|
|
138
143
|
'uiSplat',
|
|
139
144
|
'uiWindow',
|
|
140
145
|
];
|
|
@@ -299,6 +304,26 @@ export default class TeraFy {
|
|
|
299
304
|
}
|
|
300
305
|
|
|
301
306
|
|
|
307
|
+
applyProjectStatePatch(patch) {
|
|
308
|
+
if (this.settings.devMode && this.settings.debugPaths) {
|
|
309
|
+
if (!Array.isArray(this.settings.debugPaths)) throw new Error('teraFyClient.settings.debugPaths should be either null or an Array<String>');
|
|
310
|
+
|
|
311
|
+
let watchedPaths = patch
|
|
312
|
+
.filter(patch => this.settings.debugPaths.some(debugPath =>
|
|
313
|
+
patch.path.join('.').slice(0, debugPath.length) == debugPath
|
|
314
|
+
))
|
|
315
|
+
.map(patch => patch.path.join('.'));
|
|
316
|
+
|
|
317
|
+
if (watchedPaths.length > 0) {
|
|
318
|
+
console.info('Detected writes to', watchedPaths, '- entering debugging mode');
|
|
319
|
+
debugger;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return this.rpc('applyProjectStatePatch', patch);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
302
327
|
/**
|
|
303
328
|
* Client function which accepts a patch from the server and applies it to local project state
|
|
304
329
|
* The patch should follow the [JSPatch](http://jsonpatch.com) standard
|
|
@@ -340,7 +365,20 @@ export default class TeraFy {
|
|
|
340
365
|
|
|
341
366
|
const context = this;
|
|
342
367
|
return this.init.promise = Promise.resolve()
|
|
343
|
-
.then(()=> this.debug('INFO', 4, '[0/6] Init
|
|
368
|
+
.then(()=> this.debug('INFO', 4, '[0/6] Init', this.settings.siteUrl))
|
|
369
|
+
.then(()=> { // Init various options for optimized access
|
|
370
|
+
if (!this.settings.devMode) return; // Not in dev mode
|
|
371
|
+
this.settings.debugPaths =
|
|
372
|
+
!this.settings.debugPaths ? null // Falsy - disable
|
|
373
|
+
: Array.isArray(this.settings.debugPaths) ? this.settings.debugPaths.map(path =>
|
|
374
|
+
Array.isArray(path) ? path.join('.') // Transform arrays into dotted notation
|
|
375
|
+
: typeof path == 'string' ? path // Assume already in dotted notation
|
|
376
|
+
: (()=> { throw new Error('Unknown path type - should be an array or string in dotted notation') })()
|
|
377
|
+
)
|
|
378
|
+
: (()=> { throw new Error('Unknown terafyClient.settings.debugPaths type') })()
|
|
379
|
+
|
|
380
|
+
this.debug('INFO', 0, 'Watching state paths', this.settings.debugPaths);
|
|
381
|
+
})
|
|
344
382
|
.then(()=> this.detectMode())
|
|
345
383
|
.then(mode => {
|
|
346
384
|
this.debug('INFO', 4, '[1/6] Setting client mode to', mode);
|
|
@@ -480,7 +518,10 @@ export default class TeraFy {
|
|
|
480
518
|
let handshakeCount = 0;
|
|
481
519
|
let handshakeTimer;
|
|
482
520
|
|
|
483
|
-
let handshakeTimeout = setTimeout(()=>
|
|
521
|
+
let handshakeTimeout = setTimeout(()=> {
|
|
522
|
+
clearTimeout(handshakeTimer);
|
|
523
|
+
reject('TIMEOUT');
|
|
524
|
+
}, settings.handshakeTimeout);
|
|
484
525
|
|
|
485
526
|
const tryHandshake = ()=> {
|
|
486
527
|
this.debug('INFO', 4, 'Trying handshake', ++handshakeCount);
|
|
@@ -524,8 +565,8 @@ export default class TeraFy {
|
|
|
524
565
|
'height: 150px;',
|
|
525
566
|
'background: transparent;',
|
|
526
567
|
|
|
527
|
-
// Minimize /
|
|
528
|
-
'&.minimized.dev-mode {',
|
|
568
|
+
// Minimize / de-minimize functionality {{{
|
|
569
|
+
'body:not(.tera-fy-focus) &.minimized.dev-mode {',
|
|
529
570
|
'background: var(--TERA-accent) !important;',
|
|
530
571
|
'opacity: 0.5;',
|
|
531
572
|
'right: 0px;',
|
|
@@ -560,7 +601,7 @@ export default class TeraFy {
|
|
|
560
601
|
'}',
|
|
561
602
|
'}',
|
|
562
603
|
|
|
563
|
-
'&:not(.minimized) {',
|
|
604
|
+
'body:not(.tera-fy-focus) &:not(.minimized) {',
|
|
564
605
|
'&::before {',
|
|
565
606
|
'display: flex;',
|
|
566
607
|
'align-items: center;',
|
|
@@ -1266,6 +1307,20 @@ export default class TeraFy {
|
|
|
1266
1307
|
*/
|
|
1267
1308
|
|
|
1268
1309
|
|
|
1310
|
+
/**
|
|
1311
|
+
* Present a simple ok/cancel dialog to the user
|
|
1312
|
+
*
|
|
1313
|
+
* @function uiConfirm
|
|
1314
|
+
* @param {String} text The text to display
|
|
1315
|
+
*
|
|
1316
|
+
* @param {Object} [options] Additional options to mutate behaviour
|
|
1317
|
+
* @param {String} [options.title='TERA'] The title of the confirmation box
|
|
1318
|
+
* @param {Boolean} [options.isHtml=false] If falsy the text is rendered as plain-text otherwise it will be assumed as HTML content
|
|
1319
|
+
*
|
|
1320
|
+
* @returns {Promise} A promise which resolves with `Promise.resolve('OK')` or rejects with `Promise.reject('CANCEL')`
|
|
1321
|
+
*/
|
|
1322
|
+
|
|
1323
|
+
|
|
1269
1324
|
/**
|
|
1270
1325
|
* Display, update or dispose of windows for long running tasks
|
|
1271
1326
|
* All options are cumulative - i.e. they are merged with other options previously provided
|
|
@@ -1284,6 +1339,31 @@ export default class TeraFy {
|
|
|
1284
1339
|
*/
|
|
1285
1340
|
|
|
1286
1341
|
|
|
1342
|
+
/**
|
|
1343
|
+
* Prompt the user for an input, responding with a Promisable value
|
|
1344
|
+
*
|
|
1345
|
+
* @function uiPrompt
|
|
1346
|
+
* @param {Object} [options] Additional options to mutate behaviour
|
|
1347
|
+
* @param {String} [options.value] Current or default value to display pre-filled
|
|
1348
|
+
* @param {String} [options.title='Input required'] The dialog title to display
|
|
1349
|
+
* @param {String} [options.body] Optional additional body text
|
|
1350
|
+
* @param {Boolean} [options.bodyHtml=false] If truthy, treat the body as HTML
|
|
1351
|
+
* @param {String} [options.placeholder] Optional placeholder text
|
|
1352
|
+
*
|
|
1353
|
+
* @returns {Promise<*>} Either the eventual user value or a throw with `Promise.reject('CANCEL')`
|
|
1354
|
+
*/
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
/**
|
|
1358
|
+
* Catch an error using the TERA error handler
|
|
1359
|
+
*
|
|
1360
|
+
* @function uiThrow
|
|
1361
|
+
* @param {Error|Object|String} error Error to handle, generally an Error object but can be a POJO or a scalar string
|
|
1362
|
+
*
|
|
1363
|
+
* @returns {Void} This function is fatal
|
|
1364
|
+
*/
|
|
1365
|
+
|
|
1366
|
+
|
|
1287
1367
|
/**
|
|
1288
1368
|
* Open a popup window containing a new site
|
|
1289
1369
|
*
|
package/lib/terafy.server.js
CHANGED
|
@@ -1427,7 +1427,7 @@ export default class TeraFyServer {
|
|
|
1427
1427
|
}
|
|
1428
1428
|
// }}}
|
|
1429
1429
|
|
|
1430
|
-
// UI - uiAlert(), uiProgress(), uiWindow(), uiSplat() {{{
|
|
1430
|
+
// UI - uiAlert(), uiConfirm(), uiProgress(), uiPrompt(), uiThrow(), uiWindow(), uiSplat() {{{
|
|
1431
1431
|
/**
|
|
1432
1432
|
* Display simple text within TERA
|
|
1433
1433
|
*
|
|
@@ -1462,6 +1462,48 @@ export default class TeraFyServer {
|
|
|
1462
1462
|
}
|
|
1463
1463
|
|
|
1464
1464
|
|
|
1465
|
+
/**
|
|
1466
|
+
* Present a simple ok/cancel dialog to the user
|
|
1467
|
+
*
|
|
1468
|
+
* @param {String} text The text to display
|
|
1469
|
+
*
|
|
1470
|
+
* @param {Object} [options] Additional options to mutate behaviour
|
|
1471
|
+
* @param {String} [options.title='TERA'] The title of the confirmation box
|
|
1472
|
+
* @param {Boolean} [options.isHtml=false] If falsy the text is rendered as plain-text otherwise it will be assumed as HTML content
|
|
1473
|
+
*
|
|
1474
|
+
* @returns {Promise} A promise which resolves with `Promise.resolve('OK')` or rejects with `Promise.reject('CANCEL')`
|
|
1475
|
+
*/
|
|
1476
|
+
uiConfirm(text, options) {
|
|
1477
|
+
let settings = {
|
|
1478
|
+
title: 'TERA',
|
|
1479
|
+
isHtml: false,
|
|
1480
|
+
...options,
|
|
1481
|
+
};
|
|
1482
|
+
|
|
1483
|
+
return this.requestFocus(()=>
|
|
1484
|
+
app.service('$prompt').dialog({
|
|
1485
|
+
title: settings.title,
|
|
1486
|
+
body: text,
|
|
1487
|
+
isHtml: settings.isHtml,
|
|
1488
|
+
buttons: [
|
|
1489
|
+
{
|
|
1490
|
+
title: 'OK',
|
|
1491
|
+
class: 'btn btn-success',
|
|
1492
|
+
click: 'resolve',
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
title: 'Cancel',
|
|
1496
|
+
class: 'btn btn-danger',
|
|
1497
|
+
click: 'reject',
|
|
1498
|
+
},
|
|
1499
|
+
],
|
|
1500
|
+
})
|
|
1501
|
+
.then(()=> 'OK')
|
|
1502
|
+
.catch(()=> Promise.reject('CANCEL'))
|
|
1503
|
+
);
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
|
|
1465
1507
|
/**
|
|
1466
1508
|
* Display, update or dispose of windows for long running tasks
|
|
1467
1509
|
* All options are cumulative - i.e. they are merged with other options previously provided
|
|
@@ -1517,6 +1559,60 @@ export default class TeraFyServer {
|
|
|
1517
1559
|
uiProgressPromise;
|
|
1518
1560
|
|
|
1519
1561
|
|
|
1562
|
+
/**
|
|
1563
|
+
* Prompt the user for an input, responding with a Promisable value
|
|
1564
|
+
*
|
|
1565
|
+
* @param {Object} [options] Additional options to mutate behaviour
|
|
1566
|
+
* @param {String} [options.value] Current or default value to display pre-filled
|
|
1567
|
+
* @param {String} [options.title='Input required'] The dialog title to display
|
|
1568
|
+
* @param {String} [options.body] Optional additional body text
|
|
1569
|
+
* @param {Boolean} [options.bodyHtml=false] If truthy, treat the body as HTML
|
|
1570
|
+
* @param {String} [options.placeholder] Optional placeholder text
|
|
1571
|
+
*
|
|
1572
|
+
* @returns {Promise<*>} Either the eventual user value or a throw with `Promise.reject('CANCEL')`
|
|
1573
|
+
*/
|
|
1574
|
+
uiPrompt(options) {
|
|
1575
|
+
let settings = {
|
|
1576
|
+
title: 'Input required',
|
|
1577
|
+
value: '',
|
|
1578
|
+
body: '',
|
|
1579
|
+
bodyHtml: false,
|
|
1580
|
+
placeholder: '',
|
|
1581
|
+
...options,
|
|
1582
|
+
};
|
|
1583
|
+
|
|
1584
|
+
return this.requestFocus(()=>
|
|
1585
|
+
app.service('$prompt').dialog({
|
|
1586
|
+
title: settings.title,
|
|
1587
|
+
closable: true,
|
|
1588
|
+
component: 'UiPrompt',
|
|
1589
|
+
componentProps: {
|
|
1590
|
+
body: settings.body,
|
|
1591
|
+
bodyHtml: settings.bodyHtml,
|
|
1592
|
+
placeholder: settings.placeholder,
|
|
1593
|
+
value: settings.valuie,
|
|
1594
|
+
},
|
|
1595
|
+
buttons: ['ok', 'cancel'],
|
|
1596
|
+
})
|
|
1597
|
+
)
|
|
1598
|
+
.then(answer => answer || Promise.reject('CANCEL'))
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
/**
|
|
1603
|
+
* Catch an error using the TERA error handler
|
|
1604
|
+
*
|
|
1605
|
+
* @param {Error|Object|String} error Error to handle, generally an Error object but can be a POJO or a scalar string
|
|
1606
|
+
*
|
|
1607
|
+
* @returns {Void} This function is fatal
|
|
1608
|
+
*/
|
|
1609
|
+
uiThrow(error) {
|
|
1610
|
+
return this.requestFocus(()=>
|
|
1611
|
+
app.service('$errors').catch(error)
|
|
1612
|
+
);
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
|
|
1520
1616
|
/**
|
|
1521
1617
|
* Open a popup window containing a new site
|
|
1522
1618
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iebh/tera-fy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
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 --serve --servedir=.",
|
|
@@ -70,20 +70,21 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"detect-port": "^1.6.1",
|
|
73
|
-
"filesize": "^10.1.
|
|
73
|
+
"filesize": "^10.1.4",
|
|
74
74
|
"http-proxy": "^1.18.1",
|
|
75
75
|
"just-diff": "^6.0.2",
|
|
76
76
|
"lodash-es": "^4.17.21",
|
|
77
77
|
"mitt": "^3.0.1",
|
|
78
|
-
"nanoid": "^5.0.
|
|
79
|
-
"release-it": "^17.
|
|
78
|
+
"nanoid": "^5.0.7",
|
|
79
|
+
"release-it": "^17.5.0"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@momsfriendlydevco/eslint-config": "^
|
|
82
|
+
"@momsfriendlydevco/eslint-config": "^2.0.1",
|
|
83
83
|
"@release-it/conventional-changelog": "^8.0.1",
|
|
84
84
|
"concurrently": "^8.2.2",
|
|
85
|
-
"documentation": "^14.0.
|
|
86
|
-
"esbuild": "^0.
|
|
85
|
+
"documentation": "^14.0.3",
|
|
86
|
+
"esbuild": "^0.23.0",
|
|
87
|
+
"eslint": "^9.6.0"
|
|
87
88
|
},
|
|
88
89
|
"peerDependencies": {
|
|
89
90
|
"vue": "^3.0.0"
|
|
@@ -93,17 +94,6 @@
|
|
|
93
94
|
"just-diff-apply": "^5.5.0",
|
|
94
95
|
"vue": "^3.3.7"
|
|
95
96
|
},
|
|
96
|
-
"eslintConfig": {
|
|
97
|
-
"extends": "@momsfriendlydevco",
|
|
98
|
-
"env": {
|
|
99
|
-
"es6": true,
|
|
100
|
-
"node": true
|
|
101
|
-
},
|
|
102
|
-
"parserOptions": {
|
|
103
|
-
"ecmaVersion": 13,
|
|
104
|
-
"sourceType": "module"
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
97
|
"release-it": {
|
|
108
98
|
"git": {
|
|
109
99
|
"addUntrackedFiles": false,
|