@iebh/tera-fy 1.5.0 → 1.6.1
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 +21 -0
- package/api.md +457 -417
- package/dist/plugin.vue2.es2019.js +1 -1
- package/dist/terafy.es2019.js +2 -2
- package/dist/terafy.js +1 -1
- package/lib/projectFile.js +25 -4
- package/lib/terafy.client.js +39 -10
- package/lib/terafy.server.js +73 -40
- package/package.json +6 -3
- package/plugins/vue2.js +5 -3
package/lib/terafy.client.js
CHANGED
|
@@ -101,6 +101,8 @@ export default class TeraFy {
|
|
|
101
101
|
'getProjectState',
|
|
102
102
|
'setProjectState',
|
|
103
103
|
'setProjectStateDefaults',
|
|
104
|
+
'setProjectStateFlush',
|
|
105
|
+
'setProjectStateRefresh',
|
|
104
106
|
'saveProjectState',
|
|
105
107
|
'replaceProjectState',
|
|
106
108
|
'applyProjectStatePatch',
|
|
@@ -331,25 +333,34 @@ export default class TeraFy {
|
|
|
331
333
|
|
|
332
334
|
const context = this;
|
|
333
335
|
return this.init.promise = Promise.resolve()
|
|
336
|
+
.then(()=> this.debug('INFO', 4, '[0/5] Init using server', this.settings.siteUrl))
|
|
334
337
|
.then(()=> this.detectMode())
|
|
335
|
-
.then(mode =>
|
|
338
|
+
.then(mode => {
|
|
339
|
+
this.debug('INFO', 4, '[1/5] Setting client mode to', mode);
|
|
340
|
+
this.settings.mode = mode;
|
|
341
|
+
})
|
|
342
|
+
.then(()=> this.debug('INFO', 4, '[2/5] Injecting comms + styles + methods'))
|
|
336
343
|
.then(()=> Promise.all([
|
|
337
344
|
// Init core functions async
|
|
338
345
|
this.injectComms(),
|
|
339
346
|
this.injectStylesheet(),
|
|
340
347
|
this.injectMethods(),
|
|
341
348
|
]))
|
|
349
|
+
.then(()=> this.debug('INFO', 4, '[3/5] Set server mode'))
|
|
342
350
|
.then(()=> this.rpc('setServerMode', // Tell server what mode its in
|
|
343
351
|
this.settings.mode == 'child' ? 'embedded'
|
|
344
352
|
: this.settings.mode == 'parent' ? 'frame'
|
|
345
353
|
: this.settings.mode == 'popup' ? 'popup'
|
|
346
354
|
: (()=> { throw(`Unknown server mode "${this.settings.mode}"`) })()
|
|
347
355
|
))
|
|
356
|
+
.then(()=> this.debug('INFO', 4, '[4/5] Run client plugins'))
|
|
348
357
|
.then(()=> Promise.all( // Init all plugins (with this outer module as the context)
|
|
349
358
|
this.plugins.map(plugin =>
|
|
350
359
|
plugin.init.call(context, this.settings)
|
|
351
360
|
)
|
|
352
361
|
))
|
|
362
|
+
.then(()=> this.debug('INFO', 4, '[5/5] Init complete'))
|
|
363
|
+
.catch(e => this.debug('WARN', 0, 'Init caught error', e))
|
|
353
364
|
}
|
|
354
365
|
|
|
355
366
|
|
|
@@ -816,6 +827,24 @@ export default class TeraFy {
|
|
|
816
827
|
*/
|
|
817
828
|
|
|
818
829
|
|
|
830
|
+
/**
|
|
831
|
+
* Force copying local changes to the server
|
|
832
|
+
* This is only ever needed when saving large quantities of data that need to be immediately available
|
|
833
|
+
*
|
|
834
|
+
* @function setProjectStateFlush
|
|
835
|
+
* @returns {Promise} A promise which resolves when the operation has completed
|
|
836
|
+
*/
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Force refetching the remote project state into local
|
|
841
|
+
* This is only ever needed when saving large quantities of data that need to be immediately available
|
|
842
|
+
*
|
|
843
|
+
* @function setProjectStateRefresh
|
|
844
|
+
* @returns {Promise} A promise which resolves when the operation has completed
|
|
845
|
+
*/
|
|
846
|
+
|
|
847
|
+
|
|
819
848
|
/**
|
|
820
849
|
* Force-Save the currently active project state
|
|
821
850
|
*
|
|
@@ -918,11 +947,11 @@ export default class TeraFy {
|
|
|
918
947
|
/**
|
|
919
948
|
* Fetch a project file
|
|
920
949
|
*
|
|
921
|
-
* @param {String}
|
|
950
|
+
* @param {String} id File ID to read
|
|
922
951
|
* @returns {Promise<Blob>} The eventual fetched file as a blob
|
|
923
952
|
*/
|
|
924
|
-
getProjectFile(
|
|
925
|
-
return this.rpc('getProjectFile',
|
|
953
|
+
getProjectFile(id) {
|
|
954
|
+
return this.rpc('getProjectFile', id)
|
|
926
955
|
.then(file => file
|
|
927
956
|
? new ProjectFile({
|
|
928
957
|
tera: this,
|
|
@@ -937,7 +966,7 @@ export default class TeraFy {
|
|
|
937
966
|
* Replace a project files contents
|
|
938
967
|
*
|
|
939
968
|
* @function setProjectFile
|
|
940
|
-
* @param {String}
|
|
969
|
+
* @param {String} id File to overwrite
|
|
941
970
|
* @param {File|Blob|FormData|Object|Array} contents The new file contents
|
|
942
971
|
* @returns {Promise} A promise which will resolve when the write operation has completed
|
|
943
972
|
*/
|
|
@@ -966,7 +995,7 @@ export default class TeraFy {
|
|
|
966
995
|
* Fetch + convert a project file into a library of citations
|
|
967
996
|
*
|
|
968
997
|
* @function getProjectLibrary
|
|
969
|
-
* @param {String}
|
|
998
|
+
* @param {String} id File ID to read
|
|
970
999
|
*
|
|
971
1000
|
* @param {Object} [options] Additional options to mutate behaviour
|
|
972
1001
|
* @param {String} [options.format='json'] Format for the file. ENUM: 'pojo' (return a parsed JS collection), 'blob' (raw JS Blob object), 'file' (named JS File object)
|
|
@@ -982,17 +1011,17 @@ export default class TeraFy {
|
|
|
982
1011
|
* Save back a citation library from some input
|
|
983
1012
|
*
|
|
984
1013
|
* @function setProjectLibrary
|
|
985
|
-
* @param {String} [
|
|
1014
|
+
* @param {String} [id] File ID to save back to, if omitted a file will be prompted for
|
|
986
1015
|
* @param {Array<RefLibRef>|Blob|File} [refs] Collection of references for the selected library or the raw Blob/File
|
|
987
1016
|
*
|
|
988
1017
|
* @param {Object} [options] Additional options to mutate behaviour
|
|
989
|
-
* @param {String} [options.
|
|
1018
|
+
* @param {String} [options.id] Alternate method to specify the file ID to save as, if omitted one will be prompted for
|
|
990
1019
|
* @param {Array<RefLibRef>|Blob|File} [options.refs] Alternate method to specify the refs to save as an array or raw Blob/File
|
|
991
1020
|
* @param {String} [options.format='json'] Input format used. ENUM: 'pojo' (return a parsed JS collection), 'blob' (raw JS Blob object), 'file' (named JS File object)
|
|
992
1021
|
* @param {Boolean} [options.autoRequire=true] Run `requireProject()` automatically before continuing
|
|
993
1022
|
* @param {String} [options.hint] Hint to store against the library. Generally corresponds to the current operation being performed - e.g. 'deduped'
|
|
994
|
-
* @param {String} [options.filename] Suggested filename if
|
|
995
|
-
* @param {String} [options.title='Save citation library'] Dialog title if
|
|
1023
|
+
* @param {String} [options.filename] Suggested filename if `id` is unspecified
|
|
1024
|
+
* @param {String} [options.title='Save citation library'] Dialog title if `id` is unspecified and a prompt is necessary
|
|
996
1025
|
* @param {Boolean} [options.overwrite=true] Allow existing file upsert
|
|
997
1026
|
* @param {Object} [options.meta] Optional meta data to merge into the file data
|
|
998
1027
|
*
|
package/lib/terafy.server.js
CHANGED
|
@@ -757,10 +757,15 @@ export default class TeraFyServer {
|
|
|
757
757
|
* @param {String|Array<String>} [path] The sub-path within the project state to set, if unspecifed the entire target is used as a target and a save operation is forced
|
|
758
758
|
* @param {*} value The value to set as the default structure
|
|
759
759
|
* @param {Object} [options] Additional options to mutate behaviour, see setProjectState() for the full list of supported options
|
|
760
|
+
* @param {Boolean} [options.flush=true] Force a re-read from the server after setting, prevents race conditions with large objects. Calls `setProjectStateFlush()` after applying defaults
|
|
760
761
|
*
|
|
761
762
|
* @returns {Promise<*>} A promise which resolves to the eventual input value after defaults have been applied
|
|
762
763
|
*/
|
|
763
764
|
setProjectStateDefaults(path, value, options) {
|
|
765
|
+
let settings = {
|
|
766
|
+
flush: true,
|
|
767
|
+
...options,
|
|
768
|
+
};
|
|
764
769
|
if (!app.service('$projects').active) throw new Error('No active project');
|
|
765
770
|
|
|
766
771
|
let target = app.service('$projects').active;
|
|
@@ -771,18 +776,52 @@ export default class TeraFyServer {
|
|
|
771
776
|
value,
|
|
772
777
|
{
|
|
773
778
|
strategy: 'defaults',
|
|
774
|
-
...
|
|
779
|
+
...settings,
|
|
775
780
|
},
|
|
776
781
|
)
|
|
782
|
+
.then(()=> settings.flush && this.setProjectStateFlush())
|
|
777
783
|
.then(()=> pathTools.get(target, path));
|
|
778
784
|
} else { // Called as (value) - Populate entire project layout
|
|
779
785
|
pathTools.defaults(target, path);
|
|
786
|
+
this.debug('INFO', 1, 'setProjectStateDefaults', {
|
|
787
|
+
defaults: path,
|
|
788
|
+
newState: cloneDeep(target),
|
|
789
|
+
});
|
|
780
790
|
return this.saveProjectState()
|
|
791
|
+
.then(()=> settings.flush && this.setProjectStateFlush())
|
|
781
792
|
.then(()=> target);
|
|
782
793
|
}
|
|
783
794
|
}
|
|
784
795
|
|
|
785
796
|
|
|
797
|
+
/**
|
|
798
|
+
* Force copying local changes to the server
|
|
799
|
+
* This is only ever needed when saving large quantities of data that need to be immediately available
|
|
800
|
+
*
|
|
801
|
+
* @returns {Promise} A promise which resolves when the operation has completed
|
|
802
|
+
*/
|
|
803
|
+
setProjectStateFlush() {
|
|
804
|
+
this.debug('INFO', 1, 'Force project state flush!');
|
|
805
|
+
if (!app.service('$projects').active) throw new Error('No active project');
|
|
806
|
+
return app.service('$projects').active.$touchLocal()
|
|
807
|
+
.then(()=> null)
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Force refetching the remote project state into local
|
|
813
|
+
*
|
|
814
|
+
* @returns {Promise} A promise which resolves when the operation has completed
|
|
815
|
+
*/
|
|
816
|
+
setProjectStateRefresh() {
|
|
817
|
+
this.debug('INFO', 1, 'Force project state refresh!');
|
|
818
|
+
if (!app.service('$projects').active) throw new Error('No active project');
|
|
819
|
+
return app.service('$projects').active.$read({force: true})
|
|
820
|
+
.then(()=> this.debug('INFO', 2, 'Forced project state refresh!', {state: app.service('$projects').active}))
|
|
821
|
+
.then(()=> null)
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
|
|
786
825
|
/**
|
|
787
826
|
* Force-Save the currently active project state
|
|
788
827
|
*
|
|
@@ -951,11 +990,11 @@ export default class TeraFyServer {
|
|
|
951
990
|
|
|
952
991
|
/**
|
|
953
992
|
* Fetch a project file
|
|
954
|
-
* @param {String}
|
|
993
|
+
* @param {String} id File ID to read
|
|
955
994
|
* @returns {Promise<Blob>} The eventual fetched file as a blob
|
|
956
995
|
*/
|
|
957
|
-
getProjectFile(
|
|
958
|
-
return app.service('$supabase').fileGet(
|
|
996
|
+
getProjectFile(id) {
|
|
997
|
+
return app.service('$supabase').fileGet(app.service('$projects').decodeFilePath(id), {
|
|
959
998
|
toast: false,
|
|
960
999
|
});
|
|
961
1000
|
}
|
|
@@ -964,12 +1003,12 @@ export default class TeraFyServer {
|
|
|
964
1003
|
/**
|
|
965
1004
|
* Replace a project files contents
|
|
966
1005
|
*
|
|
967
|
-
* @param {String}
|
|
1006
|
+
* @param {String} id File to overwrite
|
|
968
1007
|
* @param {File|Blob|FormData|Object|Array} contents The new file contents
|
|
969
1008
|
* @returns {Promise} A promise which will resolve when the write operation has completed
|
|
970
1009
|
*/
|
|
971
|
-
setProjectFile(
|
|
972
|
-
return app.service('$supabase').fileSet(
|
|
1010
|
+
setProjectFile(id, contents) {
|
|
1011
|
+
return app.service('$supabase').fileSet(app.service('$projects').decodeFilePath(id), contents, {
|
|
973
1012
|
overwrite: true,
|
|
974
1013
|
toast: false,
|
|
975
1014
|
});
|
|
@@ -1019,7 +1058,7 @@ export default class TeraFyServer {
|
|
|
1019
1058
|
/**
|
|
1020
1059
|
* Fetch + convert a project file into a library of citations
|
|
1021
1060
|
*
|
|
1022
|
-
* @param {String}
|
|
1061
|
+
* @param {String} id File ID to read
|
|
1023
1062
|
*
|
|
1024
1063
|
* @param {Object} [options] Additional options to mutate behaviour
|
|
1025
1064
|
* @param {String} [options.format='json'] Format for the file. ENUM: 'pojo' (return a parsed JS collection), 'blob' (raw JS Blob object), 'file' (named JS File object)
|
|
@@ -1029,7 +1068,7 @@ export default class TeraFyServer {
|
|
|
1029
1068
|
*
|
|
1030
1069
|
* @returns {Promise<Array<Ref>>|Promise<*>} A collection of references (default bevahiour) or a whatever format was requested
|
|
1031
1070
|
*/
|
|
1032
|
-
getProjectLibrary(
|
|
1071
|
+
getProjectLibrary(id, options) {
|
|
1033
1072
|
let settings = {
|
|
1034
1073
|
format: 'pojo',
|
|
1035
1074
|
autoRequire: true,
|
|
@@ -1038,9 +1077,11 @@ export default class TeraFyServer {
|
|
|
1038
1077
|
...options,
|
|
1039
1078
|
};
|
|
1040
1079
|
|
|
1080
|
+
let filePath = app.service('$projects').decodeFilePath(id);
|
|
1081
|
+
|
|
1041
1082
|
return Promise.resolve()
|
|
1042
1083
|
.then(()=> settings.autoRequire && this.requireProject())
|
|
1043
|
-
.then(()=> app.service('$supabase').fileGet(
|
|
1084
|
+
.then(()=> app.service('$supabase').fileGet(filePath, {
|
|
1044
1085
|
toast: false,
|
|
1045
1086
|
}))
|
|
1046
1087
|
.then(blob => {
|
|
@@ -1050,7 +1091,7 @@ export default class TeraFyServer {
|
|
|
1050
1091
|
return Reflib.uploadFile({
|
|
1051
1092
|
file: new File(
|
|
1052
1093
|
[blob],
|
|
1053
|
-
app.service('$supabase')._parsePath(
|
|
1094
|
+
app.service('$supabase')._parsePath(filePath).basename,
|
|
1054
1095
|
),
|
|
1055
1096
|
});
|
|
1056
1097
|
case 'blob':
|
|
@@ -1058,7 +1099,7 @@ export default class TeraFyServer {
|
|
|
1058
1099
|
case 'file':
|
|
1059
1100
|
return new File(
|
|
1060
1101
|
[blob],
|
|
1061
|
-
app.service('$supabase')._parsePath(
|
|
1102
|
+
app.service('$supabase')._parsePath(filePath).basename,
|
|
1062
1103
|
);
|
|
1063
1104
|
default:
|
|
1064
1105
|
throw new Error(`Unsupported library format "${settings.format}"`);
|
|
@@ -1070,23 +1111,23 @@ export default class TeraFyServer {
|
|
|
1070
1111
|
/**
|
|
1071
1112
|
* Save back a citation library from some input
|
|
1072
1113
|
*
|
|
1073
|
-
* @param {String} [
|
|
1114
|
+
* @param {String} [id] File ID to save back to, if omitted a file will be prompted for
|
|
1074
1115
|
* @param {Array<RefLibRef>|Blob|File} [refs] Collection of references for the selected library or the raw Blob/File
|
|
1075
1116
|
*
|
|
1076
1117
|
* @param {Object} [options] Additional options to mutate behaviour
|
|
1077
|
-
* @param {String} [options.
|
|
1118
|
+
* @param {String} [options.id] Alternate method to specify the file ID to save as, if omitted one will be prompted for
|
|
1078
1119
|
* @param {Array<RefLibRef>|Blob|File} [options.refs] Alternate method to specify the refs to save as an array or raw Blob/File
|
|
1079
1120
|
* @param {String} [options.format='auto'] Input format used. ENUM: 'auto' (try to figure it out from context), 'pojo' (JS array of RefLib references), 'blob' (raw JS Blob object), 'file' (named JS File object)
|
|
1080
1121
|
* @param {Boolean} [options.autoRequire=true] Run `requireProject()` automatically before continuing
|
|
1081
1122
|
* @param {String|Array<String>} [options.hint] Hint(s) to store against the library. Generally corresponds to the current operation being performed - e.g. 'deduped'
|
|
1082
|
-
* @param {String} [options.filename] Suggested filename if
|
|
1083
|
-
* @param {String} [options.title='Save citation library'] Dialog title if
|
|
1123
|
+
* @param {String} [options.filename] Suggested filename if `id` is unspecified
|
|
1124
|
+
* @param {String} [options.title='Save citation library'] Dialog title if `id` is unspecified and a prompt is necessary
|
|
1084
1125
|
* @param {Boolean} [options.overwrite=true] Allow existing file upsert
|
|
1085
1126
|
* @param {Object} [options.meta] Optional meta data to merge into the file data
|
|
1086
1127
|
*
|
|
1087
1128
|
* @returns {Promise} A promise which resolves when the save operation has completed
|
|
1088
1129
|
*/
|
|
1089
|
-
setProjectLibrary(
|
|
1130
|
+
setProjectLibrary(id, refs, options) {
|
|
1090
1131
|
let settings = {
|
|
1091
1132
|
format: 'auto',
|
|
1092
1133
|
autoRequire: true,
|
|
@@ -1096,17 +1137,18 @@ export default class TeraFyServer {
|
|
|
1096
1137
|
overwrite: true,
|
|
1097
1138
|
meta: null,
|
|
1098
1139
|
...(
|
|
1099
|
-
typeof
|
|
1100
|
-
: Array.isArray(
|
|
1101
|
-
:
|
|
1140
|
+
typeof id == 'string' && Array.isArray(refs) ? {id, refs, ...options} // Called as (id, refs, options?)
|
|
1141
|
+
: Array.isArray(id) || refs instanceof Blob || refs instanceof File ? {refs: id, ...refs} // Called as (refs, options?)
|
|
1142
|
+
: id // Called as (options?)
|
|
1102
1143
|
)
|
|
1103
1144
|
};
|
|
1104
1145
|
if (!settings.refs) throw new Error('No refs to save');
|
|
1105
1146
|
|
|
1147
|
+
let filePath; // Eventual Supabase path to use
|
|
1106
1148
|
return Promise.resolve()
|
|
1107
1149
|
.then(()=> settings.autoRequire && this.requireProject())
|
|
1108
1150
|
.then(()=> {
|
|
1109
|
-
if (settings.
|
|
1151
|
+
if (settings.id) return; // We already have a file ID specified - skip
|
|
1110
1152
|
|
|
1111
1153
|
// Prompt for a save filename
|
|
1112
1154
|
return this.selectProjectFile({
|
|
@@ -1119,14 +1161,11 @@ export default class TeraFyServer {
|
|
|
1119
1161
|
},
|
|
1120
1162
|
autoRequire: false, // Handled above anyway
|
|
1121
1163
|
})
|
|
1122
|
-
.then(
|
|
1164
|
+
.then(file => settings.id = file.id)
|
|
1123
1165
|
})
|
|
1124
|
-
.then(()=> { //
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
this.debug('INFO', 2, 'Save citation library as', path);
|
|
1166
|
+
.then(()=> { // Compute filePath
|
|
1167
|
+
filePath = app.service('$projects').decodeFilePath(settings.id);
|
|
1168
|
+
debugger; // FIXME: Untested
|
|
1130
1169
|
})
|
|
1131
1170
|
.then(()=> {
|
|
1132
1171
|
// Mutate settings.ref -> Blob or File format needed by Supabase
|
|
@@ -1145,12 +1184,12 @@ export default class TeraFyServer {
|
|
|
1145
1184
|
|
|
1146
1185
|
// Get Reflib to encode the POJO into a Blob/File
|
|
1147
1186
|
return Reflib.downloadFile(settings.refs, {
|
|
1148
|
-
filename:
|
|
1187
|
+
filename: app.service('$supabase')._parsePath(filePath).filename,
|
|
1149
1188
|
promptDownload: false, // Just return the fileBlob we hand to Supabase
|
|
1150
1189
|
})
|
|
1151
1190
|
case 'blob':
|
|
1152
1191
|
if (!(settings.refs instanceof Blob)) throw new Error("setProjectLibrary({format: 'blob'} but non-Blob provided as `refs`");
|
|
1153
|
-
return new File([settings.refs], app.service('$supabase')._parsePath(
|
|
1192
|
+
return new File([settings.refs], app.service('$supabase')._parsePath(filePath).basename);
|
|
1154
1193
|
case 'file':
|
|
1155
1194
|
if (!(settings.ref instanceof File)) throw new Error("setProjectLibrary({format: 'file'} but non-File provided as `refs`");
|
|
1156
1195
|
return settings.refs;
|
|
@@ -1158,13 +1197,7 @@ export default class TeraFyServer {
|
|
|
1158
1197
|
throw new Error(`Unsupported library format "${settings.format}"`);
|
|
1159
1198
|
}
|
|
1160
1199
|
})
|
|
1161
|
-
.then(fileBlob => app.service('$supabase').fileUpload(
|
|
1162
|
-
file: fileBlob,
|
|
1163
|
-
mode: 'encoded',
|
|
1164
|
-
overwrite: true,
|
|
1165
|
-
meta: settings.meta,
|
|
1166
|
-
transcoders: false, // We can skip transcoders as we are supplying the meta information above anyway
|
|
1167
|
-
}))
|
|
1200
|
+
.then(fileBlob => app.service('$supabase').fileUpload(filePath))
|
|
1168
1201
|
}
|
|
1169
1202
|
|
|
1170
1203
|
// }}}
|
|
@@ -1183,7 +1216,7 @@ export default class TeraFyServer {
|
|
|
1183
1216
|
}
|
|
1184
1217
|
// }}}
|
|
1185
1218
|
|
|
1186
|
-
// Webpages - setPageUrl() {{{
|
|
1219
|
+
// Webpages - setPageUrl(), setPageTitle {{{
|
|
1187
1220
|
|
|
1188
1221
|
/**
|
|
1189
1222
|
* Set an active tools URL (or path) so that it survives a refresh
|
|
@@ -1196,7 +1229,8 @@ export default class TeraFyServer {
|
|
|
1196
1229
|
|
|
1197
1230
|
let $routeMatched = app.service('$route').matched[0];
|
|
1198
1231
|
if (!$routeMatched?.name) throw new Error('No active route');
|
|
1199
|
-
if (
|
|
1232
|
+
if ($routeMatched?.path == '/embed') return this.debug('INFO', 2, 'Ignoring setPageUrl(', url, ') on when in embed mode');
|
|
1233
|
+
if (!$routeMatched?.path.endsWith('/:toolPath(.*)?')) return this.debug('INFO', 2, 'Ignoring setPageUrl(', url, ') - no active tool anyway');
|
|
1200
1234
|
|
|
1201
1235
|
app.router.push({
|
|
1202
1236
|
path: $routeMatched.path.replace(/\/:toolPath\(\.\*\)\?$/, url),
|
|
@@ -1390,6 +1424,5 @@ export default class TeraFyServer {
|
|
|
1390
1424
|
...msg,
|
|
1391
1425
|
);
|
|
1392
1426
|
}
|
|
1393
|
-
|
|
1394
1427
|
// }}}
|
|
1395
1428
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iebh/tera-fy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
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=.",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"build:docs:markdown": "documentation build lib/terafy.client.js lib/projectFile.js --format md --markdown-toc --output api.md",
|
|
13
13
|
"lint": "eslint lib plugins utils widgets",
|
|
14
14
|
"release": "release-it",
|
|
15
|
-
"watch": "nodemon --watch lib --exec npm run build"
|
|
15
|
+
"watch": "nodemon --watch lib --watch plugins --exec npm run build"
|
|
16
16
|
},
|
|
17
17
|
"type": "module",
|
|
18
18
|
"imports": {
|
|
@@ -109,7 +109,10 @@
|
|
|
109
109
|
},
|
|
110
110
|
"hooks": {
|
|
111
111
|
"before:init": "git reset HEAD -- api.md docs/ dist/",
|
|
112
|
-
"
|
|
112
|
+
"before:bump": [
|
|
113
|
+
"npm run build",
|
|
114
|
+
"git add api.md docs/ dist/"
|
|
115
|
+
]
|
|
113
116
|
},
|
|
114
117
|
"plugins": {
|
|
115
118
|
"@release-it/conventional-changelog": {
|
package/plugins/vue2.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {cloneDeep} from 'lodash-es';
|
|
1
|
+
import {cloneDeep, isPlainObject} from 'lodash-es';
|
|
2
2
|
import TeraFyPluginBase from './base.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -93,6 +93,7 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
93
93
|
if (settings.read) {
|
|
94
94
|
this.events.on(`update:projects/${stateObservable.id}`, newState => {
|
|
95
95
|
skipUpdate++; // Skip next update as we're updating our own state anyway
|
|
96
|
+
this.debug('INFO', 5, 'Update Vue2 Remote->Local', {new: newState, old: stateObservable});
|
|
96
97
|
this.merge(stateObservable, newState);
|
|
97
98
|
});
|
|
98
99
|
}
|
|
@@ -114,6 +115,7 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
114
115
|
return;
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
this.debug('INFO', 5, 'Update Vue2 Local->Remote', {new: newVal, old: oldVal});
|
|
117
119
|
this.createProjectStatePatch(newVal, oldVal);
|
|
118
120
|
oldVal = cloneDeep(snapshot);
|
|
119
121
|
},
|
|
@@ -140,9 +142,9 @@ export default class TeraFyPluginVue2 extends TeraFyPluginBase {
|
|
|
140
142
|
payload.forEach(pl =>
|
|
141
143
|
Object.keys(pl)
|
|
142
144
|
.forEach(k => {
|
|
143
|
-
if (
|
|
145
|
+
if (isPlainObject(pl[k])) { // Setting sub-objects - we need to recurse these in Vue2 in case a sub-key gets glued on
|
|
144
146
|
if (!(k in target)) // Destination to merge doesn't exist yet - create it
|
|
145
|
-
this.Vue.set(target, k,
|
|
147
|
+
this.Vue.set(target, k, {});
|
|
146
148
|
|
|
147
149
|
this.merge(target[k], pl[k]);
|
|
148
150
|
} else {
|