@tailor-cms/tce-preview-runtime 0.5.5-beta.4 → 0.5.5-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@tailor-cms/tce-preview-runtime",
3
- "version": "0.5.5-beta.4",
3
+ "version": "0.5.5-beta.6",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@lukeed/uuid": "^2.0.1",
7
+ "@lukeed/csprng": "^1.0.2",
7
8
  "@mdi/font": "7.4.47",
8
9
  "@vitejs/plugin-vue": "5.2.1",
9
10
  "@vueuse/core": "12.5.0",
package/src/App.vue CHANGED
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { onMounted, ref } from 'vue';
3
3
  import ky from 'ky';
4
+ import { v4 as uuid } from '@lukeed/uuid/secure';
4
5
 
5
6
  import AppBar from './components/AppBar.vue';
6
7
  import MainLayout from './components/MainLayout.vue';
@@ -11,29 +12,33 @@ interface ContentElement {
11
12
  }
12
13
  const { VITE_SERVER_RUNTIME_URL } = import.meta.env;
13
14
  const serverRuntimeUrl = new URL(VITE_SERVER_RUNTIME_URL);
14
- const apiPrefix = '/tce-server';
15
- const api = ky.create({ prefixUrl: apiPrefix });
15
+ const api = ky.create({ prefixUrl: VITE_SERVER_RUNTIME_URL });
16
16
  const wsProtocol = serverRuntimeUrl.protocol === 'http:' ? 'ws:' : 'wss:';
17
17
 
18
18
  const element = ref<ContentElement>();
19
19
  const userState = ref({});
20
20
 
21
21
  onMounted(async () => {
22
- await getElement();
23
- const ws = new WebSocket(
24
- `${wsProtocol}//${serverRuntimeUrl.host}${apiPrefix}`,
25
- );
22
+ const url = new URL(window.location.href);
23
+ const elementId = url.searchParams.get('id');
24
+ if (!elementId) {
25
+ url.searchParams.set('id', uuid());
26
+ window.location.href = url.toString();
27
+ return;
28
+ }
29
+ await getElement(elementId);
30
+ const wsUrl = `${wsProtocol}//${serverRuntimeUrl.host}?id=${elementId}`;
31
+ const ws = new WebSocket(wsUrl);
26
32
  ws.addEventListener('message', (message) => {
27
33
  const event = JSON.parse(message.data);
28
- const elementUid = element.value?.uid;
29
- if (elementUid && elementUid !== event.entityId) return;
34
+ if (elementId && elementId !== event.entityId) return;
30
35
  if (event.type === 'userState:update') {
31
36
  userState.value = event.payload;
32
37
  }
33
38
  if (event.type === 'element:update') {
34
39
  element.value = event.payload;
35
40
  }
36
- if (event.type === 'userContext:change') getElement();
41
+ if (event.type === 'userContext:change') getElement(elementId);
37
42
  });
38
43
  });
39
44
 
@@ -41,9 +46,9 @@ function timeout(ms: number) {
41
46
  return new Promise((resolve) => setTimeout(resolve, ms));
42
47
  }
43
48
 
44
- async function getElement(): Promise<any> {
49
+ async function getElement(elementId: string): Promise<any> {
45
50
  try {
46
- const res = await api('content-element').json();
51
+ const res = await api(`content-element/${elementId}`).json();
47
52
  const { element: elementVal, userState: userStateVal } = res as any;
48
53
  element.value = elementVal;
49
54
  userState.value = userStateVal;
@@ -51,12 +56,12 @@ async function getElement(): Promise<any> {
51
56
  console.log('Error on element get', error);
52
57
  await timeout(2000);
53
58
  console.log('Retrying element get...');
54
- return getElement();
59
+ return getElement(elementId);
55
60
  }
56
61
  }
57
62
 
58
63
  async function resetElement() {
59
- const id = element.value?.id;
64
+ const id = element.value?.uid;
60
65
  if (!id) return;
61
66
  await resetState();
62
67
  const path = `content-element/${id}/reset-element`;
@@ -64,7 +69,7 @@ async function resetElement() {
64
69
  }
65
70
 
66
71
  async function resetState() {
67
- const id = element.value?.id;
72
+ const id = element.value?.uid;
68
73
  if (!id) return;
69
74
  const path = `content-element/${id}/reset-state`;
70
75
  return api.post(path);
@@ -1,21 +1,27 @@
1
1
  <template>
2
2
  <main :class="{ 'dark-theme': isDark }">
3
- <SplashLoader :is-visible="!isLoaded" />
4
- <PreviewPanel id="panelTop" :is-loaded="isLoaded" />
5
- <BottomPanel
6
- id="panelBottom"
7
- :element="props.element"
8
- :is-loaded="isLoaded"
9
- :user-state="props.userState"
10
- class="preview-panel-bottom"
11
- @reset-element="$emit('resetElement')"
12
- @reset-state="$emit('resetState')"
13
- />
3
+ <SplashLoader :is-visible="!isInitialized" />
4
+ <template v-if="isInitialized">
5
+ <PreviewPanel
6
+ id="panelTop"
7
+ :element-id="element?.uid"
8
+ :is-loaded="true"
9
+ />
10
+ <BottomPanel
11
+ id="panelBottom"
12
+ :element="props.element"
13
+ :is-loaded="true"
14
+ :user-state="props.userState"
15
+ class="preview-panel-bottom"
16
+ @reset-element="$emit('resetElement')"
17
+ @reset-state="$emit('resetState')"
18
+ />
19
+ </template>
14
20
  </main>
15
21
  </template>
16
22
 
17
23
  <script setup lang="ts">
18
- import { onMounted, ref } from 'vue';
24
+ import { computed, onMounted, ref, watch } from 'vue';
19
25
  import Split from 'split.js';
20
26
 
21
27
  import BottomPanel from './BottomPanel.vue';
@@ -27,18 +33,30 @@ defineEmits(['resetElement', 'resetState']);
27
33
  const props = defineProps<{ element: any; userState: any }>();
28
34
 
29
35
  const { isDark } = useGlobalState();
36
+
30
37
  const isLoaded = ref(false);
38
+ const isMounted = ref(false);
39
+ const isInitialized = computed(() => isMounted.value && props.element?.uid);
40
+
41
+ watch(isInitialized, (val) => {
42
+ if (val) setupPreview();
43
+ });
31
44
 
32
45
  onMounted(() => {
33
- // Client/server vertical split
34
- Split([`#panelTop`, `#panelBottom`], {
35
- direction: 'vertical',
36
- sizes: [70, 30],
37
- });
46
+ isMounted.value = true;
47
+ });
48
+
49
+ const setupPreview = () => {
50
+ setTimeout(() => {
51
+ Split([`#panelTop`, `#panelBottom`], {
52
+ direction: 'vertical',
53
+ sizes: [70, 30],
54
+ });
55
+ }, 50);
38
56
  setTimeout(() => {
39
57
  isLoaded.value = true;
40
- }, 2500);
41
- });
58
+ }, 2000);
59
+ };
42
60
  </script>
43
61
 
44
62
  <style>
@@ -3,7 +3,7 @@
3
3
  <div :id="PANELS.EDIT" class="d-flex flex-1-1-50">
4
4
  <iframe
5
5
  :key="`author-${isLoaded ? new Date().getTime() : 0}`"
6
- :src="VITE_EDIT_RUNTIME_URL"
6
+ :src="`${VITE_EDIT_RUNTIME_URL}?id=${elementId}`"
7
7
  class="flex-1-1-100"
8
8
  frameBorder="0"
9
9
  title="Edit component container"
@@ -13,7 +13,7 @@
13
13
  <div :id="PANELS.DISPLAY" class="d-flex flex-1-1-50">
14
14
  <iframe
15
15
  :key="`display-${isLoaded ? new Date().getTime() : 0}`"
16
- :src="VITE_DISPLAY_RUNTIME_URL"
16
+ :src="`${VITE_DISPLAY_RUNTIME_URL}?id=${elementId}`"
17
17
  class="flex-1-1-100"
18
18
  frameBorder="0"
19
19
  title="Display component container"
@@ -32,7 +32,7 @@ import { PANELS, useGlobalState } from '../state';
32
32
  const { VITE_DISPLAY_RUNTIME_URL, VITE_EDIT_RUNTIME_URL } = import.meta.env;
33
33
  const { previewPanelSplit } = useGlobalState();
34
34
 
35
- defineProps<{ isLoaded: Boolean }>();
35
+ defineProps<{ isLoaded: Boolean, elementId: string }>();
36
36
 
37
37
  const initPanels = () => {
38
38
  previewPanelSplit.value = Split([`#${PANELS.EDIT}`, `#${PANELS.DISPLAY}`], {
package/src/main.ts CHANGED
@@ -1,21 +1,11 @@
1
1
  import '@mdi/font/css/materialdesignicons.css';
2
2
  import 'vuetify/styles';
3
3
 
4
- import Cookies from 'universal-cookie';
5
4
  import { createApp } from 'vue';
6
5
  import { createVuetify } from 'vuetify';
7
- import { v4 as uuid } from '@lukeed/uuid/secure';
8
6
 
9
7
  import App from './App.vue';
10
8
 
11
- const CLIENT_ID_KEY = 'cekClientId';
12
- const { VITE_CODESPACES_DOMAIN: codespaceDomain } = import.meta.env;
13
- const cookieOptions: any = { path: '/' };
14
- if (codespaceDomain) cookieOptions.domain = codespaceDomain;
15
-
16
- const cookies = new Cookies(null, cookieOptions);
17
- if (!cookies.get(CLIENT_ID_KEY)) cookies.set(CLIENT_ID_KEY, uuid());
18
-
19
9
  createApp(App)
20
10
  .use(createVuetify({ icons: { defaultSet: 'mdi' } }))
21
11
  .mount('#app');
package/vite.config.ts CHANGED
@@ -25,14 +25,6 @@ export default defineConfig((): any => {
25
25
  // Accept connections from any host (Docker)
26
26
  host: '0.0.0.0',
27
27
  port: parseInt(config.PREVIEW_RUNTIME_PORT, 10),
28
- proxy: {
29
- '/tce-server': {
30
- target: config.SERVER_RUNTIME_URL,
31
- ws: true,
32
- changeOrigin: true,
33
- rewrite: (path) => path.replace(/^\/tce-server/, ''),
34
- },
35
- },
36
28
  },
37
29
  logLevel: 'warn',
38
30
  plugins: [vue(), vuetify({ autoImport: true })],