@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
@@ -0,0 +1,20 @@
1
+ import type TeraFy from "../lib/terafy.client.ts";
2
+ /**
3
+ * Base TeraFy plugin interface
4
+ * This is included as a documentation exanple only
5
+ *
6
+ * @class TeraFyPlugin
7
+ */
8
+ export default class TeraFyPlugin {
9
+ /**
10
+ * Optional function to be included when the main TeraFyClient is initalized
11
+ */
12
+ init(): void;
13
+ /**
14
+ * Instance constructor
15
+ *
16
+ * @param {TeraFy} terafy The TeraFy client this plugin is being initalized against
17
+ * @param {Object} [options] Additional options to mutate behaviour
18
+ */
19
+ constructor(terafy: TeraFy, options: Object);
20
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Base TeraFy plugin interface
3
+ * This is included as a documentation exanple only
4
+ *
5
+ * @class TeraFyPlugin
6
+ */
7
+ export default class TeraFyPlugin {
8
+ /**
9
+ * Optional function to be included when the main TeraFyClient is initalized
10
+ */
11
+ init() { }
12
+ /**
13
+ * Instance constructor
14
+ *
15
+ * @param {TeraFy} terafy The TeraFy client this plugin is being initalized against
16
+ * @param {Object} [options] Additional options to mutate behaviour
17
+ */
18
+ constructor(terafy, options) {
19
+ }
20
+ }
21
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../plugins/base.ts"],"names":[],"mappings":"AAEA;;;;;EAKE;AACF,MAAM,CAAC,OAAO,OAAO,YAAY;IAEhC;;MAEE;IACF,IAAI,KAAI,CAAC;IAGT;;;;;MAKE;IACF,YAAY,MAAc,EAAE,OAAe;IAC3C,CAAC;CACD"}
@@ -0,0 +1,62 @@
1
+ import Syncro from '../lib/syncro/syncro.js';
2
+ import TeraFyPluginBase from './base.js';
3
+ /**
4
+ * Plugin which adds Firebase / Firestore support for namespace mounts
5
+ *
6
+ * @class TeraFyPluginFirebase
7
+ */
8
+ export default class TeraFyPluginFirebase extends TeraFyPluginBase {
9
+ /**
10
+ * Lookup object of mounted Syncro objects by path
11
+ *
12
+ * @type {Object<Syncro>}
13
+ */
14
+ syncros: Record<string, Syncro>;
15
+ namespaces: Record<string, any>;
16
+ getCredentials: () => Promise<Record<string, any>>;
17
+ requireProject: () => Promise<{
18
+ id: string;
19
+ }>;
20
+ debug: (...args: any[]) => void;
21
+ /**
22
+ * @interface
23
+ * The Syncro#reactive option to use when creating new Syncro instances
24
+ * This is expected to be overriden by other plugins
25
+ * If falsy the Syncro module will fall back to its internal (POJO only) getReactive() function
26
+ *
27
+ * @name getReactive
28
+ * @type {Function} A reactive function as defined in Syncro
29
+ */
30
+ getReactive?: Function;
31
+ /**
32
+ * Setup Firebase + Firestore + Supabase
33
+ * Default credentials (Firebase + Supabase) will be retrieved from `getCredentials()` unless overriden here
34
+ *
35
+ * @param {Object} options Additional options to mutate behaviour (defaults to the main teraFy settings)
36
+ * @param {String} [options.firebaseApiKey] Firebase API key
37
+ * @param {String} [options.firebaseAuthDomain] Firebase authorized domain
38
+ * @param {String} [options.firebaseProjectId] Firebase project ID
39
+ * @param {String} [options.firebaseAppId] Firebase App ID
40
+ * @param {String} [options.supabaseUrl] Supabase URL
41
+ * @param {String} [options.supabaseKey] Supabase client key
42
+ *
43
+ * @returns {Promise} A Promise which will resolve when the init process has completed
44
+ */
45
+ init(options?: any): Promise<void>;
46
+ /**
47
+ * Mount the given namespace against `namespaces[name]`
48
+ *
49
+ * @param {'_PROJECT'|String} name The name/Syncro path of the namespace to mount (or '_PROJECT' for the project mountpoint)
50
+ *
51
+ * @returns {Promise} A promise which resolves when the operation has completed
52
+ */
53
+ _mountNamespace(name: string): Promise<void>;
54
+ /**
55
+ * Unmount the given namespace from `namespaces[name]`
56
+ *
57
+ * @param {String} name The name/Syncro path of the namespace to unmount
58
+ *
59
+ * @returns {Promise} A promise which resolves when the operation has completed
60
+ */
61
+ _unmountNamespace(name: string): Promise<void | any[]>;
62
+ }
@@ -0,0 +1,111 @@
1
+ import { initializeApp as Firebase } from 'firebase/app';
2
+ import { getFirestore as Firestore } from 'firebase/firestore';
3
+ import Supabasey from '@iebh/supabasey';
4
+ import Syncro from '../lib/syncro/syncro.js';
5
+ import TeraFyPluginBase from './base.js';
6
+ /**
7
+ * Plugin which adds Firebase / Firestore support for namespace mounts
8
+ *
9
+ * @class TeraFyPluginFirebase
10
+ */
11
+ export default class TeraFyPluginFirebase extends TeraFyPluginBase {
12
+ constructor() {
13
+ super(...arguments);
14
+ /**
15
+ * Lookup object of mounted Syncro objects by path
16
+ *
17
+ * @type {Object<Syncro>}
18
+ */
19
+ this.syncros = {};
20
+ this.namespaces = {}; // Declare namespaces property
21
+ }
22
+ /**
23
+ * Setup Firebase + Firestore + Supabase
24
+ * Default credentials (Firebase + Supabase) will be retrieved from `getCredentials()` unless overriden here
25
+ *
26
+ * @param {Object} options Additional options to mutate behaviour (defaults to the main teraFy settings)
27
+ * @param {String} [options.firebaseApiKey] Firebase API key
28
+ * @param {String} [options.firebaseAuthDomain] Firebase authorized domain
29
+ * @param {String} [options.firebaseProjectId] Firebase project ID
30
+ * @param {String} [options.firebaseAppId] Firebase App ID
31
+ * @param {String} [options.supabaseUrl] Supabase URL
32
+ * @param {String} [options.supabaseKey] Supabase client key
33
+ *
34
+ * @returns {Promise} A Promise which will resolve when the init process has completed
35
+ */
36
+ async init(options) {
37
+ let settings = {
38
+ firebaseApiKey: null,
39
+ firebaseAuthDomain: null,
40
+ firebaseProjectId: null,
41
+ firebaseAppId: null,
42
+ supabaseUrl: null,
43
+ supabaseKey: null,
44
+ ...await this.getCredentials(),
45
+ ...options,
46
+ };
47
+ let emptyValues = Object.keys(settings).filter(k => k === null);
48
+ if (emptyValues.length > 0)
49
+ throw new Error('Firebase plugin requires mandatory options: ' + emptyValues.join(', '));
50
+ Syncro.firebase = Firebase({
51
+ apiKey: settings.firebaseApiKey, // Add non-null assertion
52
+ authDomain: settings.firebaseAuthDomain, // Add non-null assertion
53
+ projectId: settings.firebaseProjectId, // Add non-null assertion
54
+ appId: settings.firebaseAppId, // Add non-null assertion
55
+ });
56
+ Syncro.firestore = Firestore(Syncro.firebase); // Use Syncro.firebase
57
+ Syncro.supabasey = await Supabasey.init({
58
+ env: {
59
+ SUPABASE_URL: settings.supabaseUrl,
60
+ SUPABASE_KEY: settings.supabaseKey, // Add non-null assertions
61
+ },
62
+ });
63
+ }
64
+ /**
65
+ * Mount the given namespace against `namespaces[name]`
66
+ *
67
+ * @param {'_PROJECT'|String} name The name/Syncro path of the namespace to mount (or '_PROJECT' for the project mountpoint)
68
+ *
69
+ * @returns {Promise} A promise which resolves when the operation has completed
70
+ */
71
+ _mountNamespace(name) {
72
+ let syncro; // Add type Syncro
73
+ return Promise.resolve()
74
+ .then(() => this.requireProject())
75
+ .then(project => {
76
+ let path = name == '_PROJECT'
77
+ ? `projects::${project.id}`
78
+ : `project_namespaces::${project.id}::${name}`;
79
+ syncro = this.syncros[name] = new Syncro(path, {
80
+ debug: (...msg) => this.debug(`SYNCRO://${path}`, ...msg), // Add type any[]
81
+ getReactive: this.getReactive, // Try to inherit this instances getReactive prop, otherwise Syncro will fall back to its default
82
+ });
83
+ // Perform the mount action
84
+ return syncro.mount();
85
+ })
86
+ .then(() => {
87
+ this.namespaces[name] = syncro.value;
88
+ });
89
+ }
90
+ /**
91
+ * Unmount the given namespace from `namespaces[name]`
92
+ *
93
+ * @param {String} name The name/Syncro path of the namespace to unmount
94
+ *
95
+ * @returns {Promise} A promise which resolves when the operation has completed
96
+ */
97
+ _unmountNamespace(name) {
98
+ let syncro = this.syncros[name]; // Create local alias for Syncro before we detach it
99
+ // Detach local state
100
+ delete this.namespaces[name];
101
+ delete this.syncros[name];
102
+ // Check if syncro exists before calling destroy
103
+ if (syncro) {
104
+ return syncro.destroy(); // Trigger Syncro distruction
105
+ }
106
+ else {
107
+ return Promise.resolve(); // Or handle the case where syncro doesn't exist
108
+ }
109
+ }
110
+ }
111
+ //# sourceMappingURL=firebase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase.js","sourceRoot":"","sources":["../../plugins/firebase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Setup a Vite local loopback
3
+ *
4
+ * @see lib/terafy.proxy.js
5
+ *
6
+ * @param {Object} [options] Options to pass to the Proxy module
7
+ * @returns {VitePlugin}
8
+ */
9
+ export default function vitePluginTeraFy(options: any): {
10
+ name: string;
11
+ apply(config: any, { command }: any): false | undefined;
12
+ };
@@ -0,0 +1,22 @@
1
+ import TeraProxy from '../lib/terafy.proxy.js';
2
+ /**
3
+ * Setup a Vite local loopback
4
+ *
5
+ * @see lib/terafy.proxy.js
6
+ *
7
+ * @param {Object} [options] Options to pass to the Proxy module
8
+ * @returns {VitePlugin}
9
+ */
10
+ export default function vitePluginTeraFy(options) {
11
+ // Vite plugin config
12
+ return {
13
+ name: 'tera-fy',
14
+ apply(config, { command }) {
15
+ // Don't run when building
16
+ if (command == 'build')
17
+ return false;
18
+ TeraProxy(options);
19
+ },
20
+ };
21
+ }
22
+ //# sourceMappingURL=vite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.js","sourceRoot":"","sources":["../../plugins/vite.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAE/C;;;;;;;EAOE;AACF,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,OAAY;IAEpD,qBAAqB;IACrB,OAAO;QACN,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,MAAW,EAAE,EAAE,OAAO,EAAO;YAElC,0BAA0B;YAC1B,IAAI,OAAO,IAAI,OAAO;gBAAE,OAAO,KAAK,CAAC;YAErC,SAAS,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;KACD,CAAA;AACF,CAAC"}
@@ -0,0 +1,68 @@
1
+ import TeraFyPluginFirebase from './firebase.js';
2
+ /**
3
+ * Vue@2 observables plugin
4
+ *
5
+ * This function is expected to be included via the `terafy.use(MODULE, OPTIONS)` syntax rather than directly
6
+ *
7
+ * @class TeraFyPluginVue2
8
+ *
9
+ * @example Implementation within a Vue@2 project `src/main.js`:
10
+ * // Include the main Tera-Fy core
11
+ * import TeraFy from '@iebh/tera-fy';
12
+ * import TerafyVue from '@iebh/tera-fy/plugins/vue2';
13
+ * let terafy = new TeraFy()
14
+ * .set('devMode', true) // Uncomment this line if you want TeraFy to be chatty
15
+ * .set('siteUrl', 'http://localhost:7334/embed') // Uncomment this line if running TERA locally
16
+ * .use(TerafyVue, { // Add the Vue plugin
17
+ * vue: window.Vue, // Assumes Vue is available on the window object
18
+ * })
19
+ *
20
+ * // Include after app boot
21
+ * const app = new Vue({ ... })
22
+ * app.$mount("#app");
23
+ * await terafy.init({app});
24
+ */
25
+ export default class TeraFyPluginVue2 extends TeraFyPluginFirebase {
26
+ /**
27
+ * Local Vue@2 library to use, set during constuctor
28
+ *
29
+ * @type {Vue}
30
+ */
31
+ Vue: any;
32
+ /**
33
+ * The root Vue app instance
34
+ * @type {any}
35
+ */
36
+ app: any;
37
+ /**
38
+ * The bound, reactive state of the active TERA project
39
+ *
40
+ * @type {Object | null}
41
+ */
42
+ project: any;
43
+ /**
44
+ * Simple incrementor to ensure unique IDs for $watch expressions
45
+ *
46
+ * @type {Number}
47
+ */
48
+ reactiveId: number;
49
+ /**
50
+ * Install into Vue@2
51
+ *
52
+ * @param {Object} options Additional options to mutate behaviour, see TeraFyPluginFirebase
53
+ * @param {Object} options.app Root level Vue app to bind against
54
+ * @param {Vue} options.Vue Vue@2 instance to bind against
55
+ * @param {String} [options.globalName='$tera'] Global property to allocate this service as within Vue2
56
+ * @param {*...} [options...] see TeraFyPluginFirebase
57
+ *
58
+ * @returns {Promise} A Promise which will resolve when the init process has completed
59
+ */
60
+ init(options: any): Promise<void>;
61
+ /** @override */
62
+ getReactive(value: any): {
63
+ doc: any;
64
+ setState: (state: any) => void;
65
+ getState: () => any;
66
+ watch: (cb: Function) => void;
67
+ };
68
+ }
@@ -0,0 +1,96 @@
1
+ import { cloneDeep, isEqual } from 'lodash-es';
2
+ import TeraFyPluginFirebase from './firebase.js';
3
+ /**
4
+ * Vue@2 observables plugin
5
+ *
6
+ * This function is expected to be included via the `terafy.use(MODULE, OPTIONS)` syntax rather than directly
7
+ *
8
+ * @class TeraFyPluginVue2
9
+ *
10
+ * @example Implementation within a Vue@2 project `src/main.js`:
11
+ * // Include the main Tera-Fy core
12
+ * import TeraFy from '@iebh/tera-fy';
13
+ * import TerafyVue from '@iebh/tera-fy/plugins/vue2';
14
+ * let terafy = new TeraFy()
15
+ * .set('devMode', true) // Uncomment this line if you want TeraFy to be chatty
16
+ * .set('siteUrl', 'http://localhost:7334/embed') // Uncomment this line if running TERA locally
17
+ * .use(TerafyVue, { // Add the Vue plugin
18
+ * vue: window.Vue, // Assumes Vue is available on the window object
19
+ * })
20
+ *
21
+ * // Include after app boot
22
+ * const app = new Vue({ ... })
23
+ * app.$mount("#app");
24
+ * await terafy.init({app});
25
+ */
26
+ export default class TeraFyPluginVue2 extends TeraFyPluginFirebase {
27
+ constructor() {
28
+ super(...arguments);
29
+ /**
30
+ * The bound, reactive state of the active TERA project
31
+ *
32
+ * @type {Object | null}
33
+ */
34
+ this.project = null;
35
+ /**
36
+ * Simple incrementor to ensure unique IDs for $watch expressions
37
+ *
38
+ * @type {Number}
39
+ */
40
+ this.reactiveId = 1001;
41
+ }
42
+ /**
43
+ * Install into Vue@2
44
+ *
45
+ * @param {Object} options Additional options to mutate behaviour, see TeraFyPluginFirebase
46
+ * @param {Object} options.app Root level Vue app to bind against
47
+ * @param {Vue} options.Vue Vue@2 instance to bind against
48
+ * @param {String} [options.globalName='$tera'] Global property to allocate this service as within Vue2
49
+ * @param {*...} [options...] see TeraFyPluginFirebase
50
+ *
51
+ * @returns {Promise} A Promise which will resolve when the init process has completed
52
+ */
53
+ async init(options) {
54
+ let settings = {
55
+ app: null,
56
+ Vue: null,
57
+ globalName: '$tera',
58
+ ...options,
59
+ };
60
+ if (!settings.Vue)
61
+ throw new Error('Vue instance to use must be specified in init options as `Vue`');
62
+ this.Vue = settings.Vue;
63
+ if (!settings.app)
64
+ throw new Error('Vue Root / App instance to use must be specified in init options as `app`');
65
+ this.app = settings.app;
66
+ // Make this module available globally
67
+ if (settings.globalName)
68
+ this.Vue.prototype[settings.globalName] = this;
69
+ await super.init(settings); // Initalize parent class Firebase functionality
70
+ // @ts-ignore
71
+ this.project = await this.mountNamespace('_PROJECT');
72
+ }
73
+ /** @override */
74
+ // @ts-ignore
75
+ getReactive(value) {
76
+ let doc = this.Vue.observable(value);
77
+ let watcherPath = `_teraFy_${this.reactiveId++}`;
78
+ this.app[watcherPath] = doc; // Attach onto app so we can use $watch later on
79
+ return {
80
+ doc,
81
+ setState: (state) => {
82
+ // Shallow copy all sub-keys into existing object (keeping the object pointer)
83
+ Object.entries(state || {})
84
+ .filter(([k]) => !isEqual(doc[k], state[k])) // Only accept changed keys
85
+ .forEach(([k, v]) => doc[k] = v);
86
+ },
87
+ getState: () => {
88
+ return cloneDeep(doc);
89
+ },
90
+ watch: (cb) => {
91
+ this.app.$watch(watcherPath, cb, { deep: true });
92
+ },
93
+ };
94
+ }
95
+ }
96
+ //# sourceMappingURL=vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue2.js","sourceRoot":"","sources":["../../plugins/vue2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AAC7C,OAAO,oBAAoB,MAAM,eAAe,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;EAsBE;AACF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,oBAAoB;IAAlE;;QAgBC;;;;UAIE;QACF,YAAO,GAAQ,IAAI,CAAC;QAGpB;;;;UAIE;QACF,eAAU,GAAG,IAAI,CAAC;IA+DnB,CAAC;IA5DA;;;;;;;;;;MAUE;IACF,KAAK,CAAC,IAAI,CAAC,OAAY;QACtB,IAAI,QAAQ,GAAG;YACd,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,IAAI;YACT,UAAU,EAAE,OAAO;YACnB,GAAG,OAAO;SACV,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACrG,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC;QAExB,IAAI,CAAC,QAAQ,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAChH,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC;QAExB,sCAAsC;QACtC,IAAI,QAAQ,CAAC,UAAU;YACtB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;QAEhD,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,gDAAgD;QAC5E,aAAa;QACb,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;IAGD,gBAAgB;IAChB,aAAa;IACb,WAAW,CAAC,KAAU;QACrB,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAErC,IAAI,WAAW,GAAG,WAAW,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,gDAAgD;QAE7E,OAAO;YACN,GAAG;YACH,QAAQ,EAAE,CAAC,KAAU,EAAE,EAAE;gBACxB,8EAA8E;gBAC9E,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;qBACzB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B;qBACvE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAClC,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACd,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,KAAK,EAAE,CAAC,EAAY,EAAE,EAAE;gBACvB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;YAChD,CAAC;SACD,CAAC;IACH,CAAC;CAED"}
@@ -0,0 +1,64 @@
1
+ import TeraFyPluginFirebase from './firebase.js';
2
+ import { App, WatchCallback } from 'vue';
3
+ /**
4
+ * Vue observables plugin
5
+ *
6
+ * This function is expected to be included via the `terafy.use(MODULE, OPTIONS)` syntax rather than directly
7
+ *
8
+ * @class TeraFyPluginVue3
9
+ *
10
+ * @example Implementation within a Vue3 / Vite project within `src/main.js`:
11
+ * import TeraFy from '@iebh/tera-fy';
12
+ * import TerafyVue from '@iebh/tera-fy/plugins/vue';
13
+ * let terafy = new TeraFy()
14
+ * .set('devMode', import.meta.env.DEV)
15
+ * .set('siteUrl', 'http://localhost:7334/embed') // Uncomment this line if running TERA locally
16
+ * .use(TerafyVue) // Add the Vue plugin
17
+ *
18
+ * terafy.init(); // Initialize everything
19
+ *
20
+ * app.use(terafy.vuePlugin({
21
+ * globalName: '$tera', // Install as vm.$tera into every component
22
+ * }));
23
+ *
24
+ * @example Accessing project state - within a Vue component
25
+ * this.$tera.active
26
+ */
27
+ export default class TeraFyPluginVue3 extends TeraFyPluginFirebase {
28
+ /**
29
+ * The bound, reactive state of the active TERA project
30
+ *
31
+ * @type {Object}
32
+ */
33
+ project: any;
34
+ /**
35
+ * Init the project including create a reactive mount for the active project
36
+ *
37
+ * @param {Object} options Additional options to mutate behaviour
38
+ * @param {*} [options...] see TeraFyPluginFirebase
39
+ */
40
+ init(options: Record<string, any>): Promise<void>;
41
+ /** @override */
42
+ getReactive(value: any): {
43
+ doc: any;
44
+ setState(state: any): void;
45
+ getState(): any;
46
+ watch(cb: WatchCallback<any, any>): void;
47
+ };
48
+ /**
49
+ * Provide a Vue@3 compatible plugin
50
+ *
51
+ * @returns {VuePlugin} A Vue@3 plugin spec
52
+ */
53
+ vuePlugin(): {
54
+ /**
55
+ * Install into Vue as a generic Vue@3 plugin
56
+ *
57
+ * @param {VueApp} app The Vue top-level app to install against
58
+ *
59
+ * @param {Object} [options] Additional options to mutate behaviour
60
+ * @param {String} [options.globalName='$tera'] Global property to allocate this service as
61
+ */
62
+ install(app: App, options: Record<string, any>): void;
63
+ };
64
+ }
@@ -0,0 +1,96 @@
1
+ import { cloneDeep } from 'lodash-es';
2
+ import TeraFyPluginFirebase from './firebase.js';
3
+ import { reactive as vueReactive, watch as vueWatch } from 'vue';
4
+ /**
5
+ * Vue observables plugin
6
+ *
7
+ * This function is expected to be included via the `terafy.use(MODULE, OPTIONS)` syntax rather than directly
8
+ *
9
+ * @class TeraFyPluginVue3
10
+ *
11
+ * @example Implementation within a Vue3 / Vite project within `src/main.js`:
12
+ * import TeraFy from '@iebh/tera-fy';
13
+ * import TerafyVue from '@iebh/tera-fy/plugins/vue';
14
+ * let terafy = new TeraFy()
15
+ * .set('devMode', import.meta.env.DEV)
16
+ * .set('siteUrl', 'http://localhost:7334/embed') // Uncomment this line if running TERA locally
17
+ * .use(TerafyVue) // Add the Vue plugin
18
+ *
19
+ * terafy.init(); // Initialize everything
20
+ *
21
+ * app.use(terafy.vuePlugin({
22
+ * globalName: '$tera', // Install as vm.$tera into every component
23
+ * }));
24
+ *
25
+ * @example Accessing project state - within a Vue component
26
+ * this.$tera.active
27
+ */
28
+ export default class TeraFyPluginVue3 extends TeraFyPluginFirebase {
29
+ constructor() {
30
+ super(...arguments);
31
+ /**
32
+ * The bound, reactive state of the active TERA project
33
+ *
34
+ * @type {Object}
35
+ */
36
+ this.project = null;
37
+ }
38
+ /**
39
+ * Init the project including create a reactive mount for the active project
40
+ *
41
+ * @param {Object} options Additional options to mutate behaviour
42
+ * @param {*} [options...] see TeraFyPluginFirebase
43
+ */
44
+ async init(options) {
45
+ await super.init(options); // Initalize parent class Firebase functionality
46
+ // Mount the project namespace
47
+ // @ts-ignore
48
+ this.project = await this.mountNamespace('_PROJECT');
49
+ }
50
+ /** @override */
51
+ // @ts-ignore
52
+ getReactive(value) {
53
+ let doc = vueReactive(value);
54
+ return {
55
+ doc,
56
+ setState(state) {
57
+ // Shallow copy all sub-keys into existing object (keeping the object pointer)
58
+ Object.entries(state || {})
59
+ .forEach(([k, v]) => doc[k] = v);
60
+ },
61
+ getState() {
62
+ return cloneDeep(doc);
63
+ },
64
+ watch(cb) {
65
+ vueWatch(doc, cb, { deep: true });
66
+ },
67
+ };
68
+ }
69
+ /**
70
+ * Provide a Vue@3 compatible plugin
71
+ *
72
+ * @returns {VuePlugin} A Vue@3 plugin spec
73
+ */
74
+ vuePlugin() {
75
+ let $tera = this;
76
+ return {
77
+ /**
78
+ * Install into Vue as a generic Vue@3 plugin
79
+ *
80
+ * @param {VueApp} app The Vue top-level app to install against
81
+ *
82
+ * @param {Object} [options] Additional options to mutate behaviour
83
+ * @param {String} [options.globalName='$tera'] Global property to allocate this service as
84
+ */
85
+ install(app, options) {
86
+ let settings = {
87
+ globalName: '$tera',
88
+ ...options,
89
+ };
90
+ // Make this module available globally
91
+ app.config.globalProperties[settings.globalName] = $tera;
92
+ },
93
+ };
94
+ }
95
+ }
96
+ //# sourceMappingURL=vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue3.js","sourceRoot":"","sources":["../../plugins/vue3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,oBAAoB,MAAM,eAAe,CAAC;AACjD,OAAO,EAAC,QAAQ,IAAI,WAAW,EAAE,KAAK,IAAI,QAAQ,EAAqB,MAAM,KAAK,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;EAuBE;AACF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,oBAAoB;IAAlE;;QAEC;;;;UAIE;QACF,YAAO,GAAQ,IAAI,CAAC;IAsErB,CAAC;IAnEA;;;;;MAKE;IACF,KAAK,CAAC,IAAI,CAAC,OAA4B;QACtC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,gDAAgD;QAE3E,8BAA8B;QAC9B,aAAa;QACb,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;IAGD,gBAAgB;IAChB,aAAa;IACb,WAAW,CAAC,KAAU;QACrB,IAAI,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO;YACN,GAAG;YACH,QAAQ,CAAC,KAAU;gBAClB,8EAA8E;gBAC9E,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;qBACzB,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAClC,CAAC;YACD,QAAQ;gBACP,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,KAAK,CAAC,EAA2B;gBAChC,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;YACjC,CAAC;SACD,CAAC;IACH,CAAC;IAGD;;;;MAIE;IACF,SAAS;QACR,IAAI,KAAK,GAAG,IAAI,CAAC;QAEjB,OAAO;YAEN;;;;;;;cAOE;YACF,OAAO,CAAC,GAAQ,EAAE,OAA4B;gBAC7C,IAAI,QAAQ,GAAG;oBACd,UAAU,EAAE,OAAO;oBACnB,GAAG,OAAO;iBACV,CAAC;gBAEF,sCAAsC;gBACtC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;YAC1D,CAAC;SAED,CAAC;IACH,CAAC;CAED"}