@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.
- package/CHANGELOG.md +38 -0
- package/api.md +68 -66
- package/dist/lib/projectFile.d.ts +182 -0
- package/dist/lib/projectFile.js +157 -0
- package/dist/lib/projectFile.js.map +1 -0
- package/dist/lib/syncro/entities.d.ts +28 -0
- package/dist/lib/syncro/entities.js +203 -0
- package/dist/lib/syncro/entities.js.map +1 -0
- package/dist/lib/syncro/keyed.d.ts +95 -0
- package/dist/lib/syncro/keyed.js +286 -0
- package/dist/lib/syncro/keyed.js.map +1 -0
- package/dist/lib/syncro/syncro.d.ts +328 -0
- package/dist/lib/syncro/syncro.js +633 -0
- package/dist/lib/syncro/syncro.js.map +1 -0
- package/dist/lib/terafy.bootstrapper.d.ts +42 -0
- package/dist/lib/terafy.bootstrapper.js +130 -0
- package/dist/lib/terafy.bootstrapper.js.map +1 -0
- package/dist/lib/terafy.client.d.ts +532 -0
- package/dist/lib/terafy.client.js +1110 -0
- package/dist/lib/terafy.client.js.map +1 -0
- package/dist/lib/terafy.proxy.d.ts +66 -0
- package/dist/lib/terafy.proxy.js +123 -0
- package/dist/lib/terafy.proxy.js.map +1 -0
- package/dist/lib/terafy.server.d.ts +607 -0
- package/dist/lib/terafy.server.js +1774 -0
- package/dist/lib/terafy.server.js.map +1 -0
- package/dist/plugin.vue2.es2019.js +30 -13
- package/dist/plugins/base.d.ts +20 -0
- package/dist/plugins/base.js +21 -0
- package/dist/plugins/base.js.map +1 -0
- package/dist/plugins/firebase.d.ts +62 -0
- package/dist/plugins/firebase.js +111 -0
- package/dist/plugins/firebase.js.map +1 -0
- package/dist/plugins/vite.d.ts +12 -0
- package/dist/plugins/vite.js +22 -0
- package/dist/plugins/vite.js.map +1 -0
- package/dist/plugins/vue2.d.ts +68 -0
- package/dist/plugins/vue2.js +96 -0
- package/dist/plugins/vue2.js.map +1 -0
- package/dist/plugins/vue3.d.ts +64 -0
- package/dist/plugins/vue3.js +96 -0
- package/dist/plugins/vue3.js.map +1 -0
- package/dist/terafy.bootstrapper.es2019.js +2 -2
- package/dist/terafy.bootstrapper.js +2 -2
- package/dist/terafy.es2019.js +2 -2
- package/dist/terafy.js +1 -1
- package/dist/utils/mixin.d.ts +11 -0
- package/dist/utils/mixin.js +15 -0
- package/dist/utils/mixin.js.map +1 -0
- package/dist/utils/pDefer.d.ts +12 -0
- package/dist/utils/pDefer.js +14 -0
- package/dist/utils/pDefer.js.map +1 -0
- package/dist/utils/pathTools.d.ts +70 -0
- package/dist/utils/pathTools.js +120 -0
- package/dist/utils/pathTools.js.map +1 -0
- package/eslint.config.js +44 -8
- package/lib/{projectFile.js → projectFile.ts} +83 -40
- package/lib/syncro/entities.ts +288 -0
- package/lib/syncro/{keyed.js → keyed.ts} +114 -57
- package/lib/syncro/{syncro.js → syncro.ts} +204 -169
- package/lib/{terafy.bootstrapper.js → terafy.bootstrapper.ts} +49 -31
- package/lib/{terafy.client.js → terafy.client.ts} +94 -86
- package/lib/{terafy.proxy.js → terafy.proxy.ts} +43 -16
- package/lib/{terafy.server.js → terafy.server.ts} +364 -223
- package/package.json +65 -26
- package/plugins/{base.js → base.ts} +3 -1
- package/plugins/{firebase.js → firebase.ts} +34 -16
- package/plugins/{vite.js → vite.ts} +3 -3
- package/plugins/{vue2.js → vue2.ts} +17 -10
- package/plugins/{vue3.js → vue3.ts} +11 -9
- package/tsconfig.json +30 -0
- package/utils/{mixin.js → mixin.ts} +1 -1
- package/utils/{pDefer.js → pDefer.ts} +10 -3
- package/utils/{pathTools.js → pathTools.ts} +11 -9
- 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"}
|