@panomc/sdk 1.0.0-dev.2 → 1.0.0-dev.21

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/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # Pano Common Assets
2
-
3
- Pano common assets repository.
1
+ # Pano Common Assets
2
+
3
+ Pano common assets repository.
package/package.json CHANGED
@@ -1,33 +1,73 @@
1
1
  {
2
2
  "name": "@panomc/sdk",
3
- "version": "1.0.0-dev.2",
3
+ "version": "1.0.0-dev.21",
4
4
  "author": "PanoMC",
5
5
  "repository": {
6
6
  "url": "https://github.com/PanoMC/sdk"
7
7
  },
8
- "publishConfig": {
9
- "access": "public"
8
+ "devDependencies": {
9
+ "svelte": "^5.46.1"
10
+ },
11
+ "peerDependencies": {
12
+ "svelte": "^5.46.1"
10
13
  },
11
- "type": "module",
12
- "files": [
13
- "dist"
14
- ],
15
- "main": "dist/index.js",
16
- "module": "dist/index.js",
17
14
  "exports": {
18
15
  ".": {
19
- "import": "./dist/index.js"
16
+ "svelte": "./src/index.js",
17
+ "default": "./src/index.js"
18
+ },
19
+ "./components": {
20
+ "svelte": "./src/components/index.js",
21
+ "default": "./src/components/index.js"
22
+ },
23
+ "./internal": {
24
+ "svelte": "./src/internal/index.js",
25
+ "default": "./src/internal/index.js"
26
+ },
27
+ "./toasts": {
28
+ "svelte": "./src/toasts/index.js",
29
+ "default": "./src/toasts/index.js"
30
+ },
31
+ "./utils/api": {
32
+ "svelte": "./src/utils/api.js",
33
+ "default": "./src/utils/api.js"
34
+ },
35
+ "./utils/auth": {
36
+ "svelte": "./src/utils/auth.js",
37
+ "default": "./src/utils/auth.js"
38
+ },
39
+ "./utils/tooltip": {
40
+ "svelte": "./src/utils/tooltip.js",
41
+ "default": "./src/utils/tooltip.js"
42
+ },
43
+ "./utils/language": {
44
+ "svelte": "./src/utils/language.js",
45
+ "default": "./src/utils/language.js"
46
+ },
47
+ "./utils/component": {
48
+ "svelte": "./src/utils/component.js",
49
+ "default": "./src/utils/component.js"
50
+ },
51
+ "./utils/text": {
52
+ "svelte": "./src/utils/text.js",
53
+ "default": "./src/utils/text.js"
54
+ },
55
+ "./variables": {
56
+ "svelte": "./src/variables.js",
57
+ "default": "./src/variables.js"
58
+ },
59
+ "./svelte": {
60
+ "svelte": "./src/svelte.js",
61
+ "default": "./src/svelte.js"
20
62
  }
21
63
  },
22
- "scripts": {
23
- "build": "vite build"
24
- },
25
- "peerDependencies": {
26
- "svelte": "^5.46.1"
64
+ "files": [
65
+ "src"
66
+ ],
67
+ "publishConfig": {
68
+ "access": "public"
27
69
  },
28
- "devDependencies": {
29
- "@sveltejs/vite-plugin-svelte": "^6.2.1",
30
- "vite": "^7.3.0",
31
- "svelte": "^5.46.1"
32
- }
70
+ "scripts": {},
71
+ "svelte": "./src/index.js",
72
+ "type": "module"
33
73
  }
@@ -0,0 +1,55 @@
1
+ const GLOBAL_KEY = '__PANO_PLUGIN_CONTEXTS__';
2
+
3
+ function getStore() {
4
+ if (!globalThis[GLOBAL_KEY]) {
5
+ globalThis[GLOBAL_KEY] = Object.create(null);
6
+ }
7
+ return globalThis[GLOBAL_KEY];
8
+ }
9
+
10
+ export function createPluginContext(pluginId) {
11
+ if (!pluginId) {
12
+ throw new Error('[PanoSDK] pluginId is required');
13
+ }
14
+
15
+ const store = getStore();
16
+
17
+ if (!store[pluginId]) {
18
+ store[pluginId] = {
19
+ context: {},
20
+ listeners: [],
21
+ };
22
+ }
23
+
24
+ const pluginStore = store[pluginId];
25
+
26
+ return {
27
+ context: pluginStore.context,
28
+
29
+ set(partial) {
30
+ if (typeof partial !== 'object' || partial === null) return;
31
+
32
+ Object.assign(pluginStore.context, partial);
33
+
34
+ pluginStore.listeners.forEach((fn) => {
35
+ try {
36
+ fn(pluginStore.context);
37
+ } catch (e) {
38
+ console.error(`[PanoSDK][${pluginId}] listener error`, e);
39
+ }
40
+ });
41
+ },
42
+
43
+ subscribe(fn) {
44
+ pluginStore.listeners.push(fn);
45
+
46
+ return () => {
47
+ pluginStore.listeners = pluginStore.listeners.filter((l) => l !== fn);
48
+ };
49
+ },
50
+
51
+ destroy() {
52
+ delete store[pluginId];
53
+ },
54
+ };
55
+ }
@@ -0,0 +1,49 @@
1
+ import { createPluginContext } from './plugin-context.js';
2
+
3
+ /**
4
+ * @typedef {import('../types.js').Pano} Pano
5
+ * @typedef {import('../types.js').PanoPluginContext} PanoPluginContext
6
+ */
7
+
8
+ export class PanoPlugin {
9
+ static isPanoPlugin = true;
10
+
11
+ /** @type {Pano} */
12
+ pano;
13
+
14
+ /** @type {PanoPluginContext} */
15
+ contextApi;
16
+
17
+ /** @type {any} */
18
+ context;
19
+
20
+ constructor({ pluginId, scope } = {}) {
21
+ if (!pluginId) {
22
+ throw new Error('[PanoPlugin] pluginId is required');
23
+ }
24
+
25
+ // plugin-scoped context
26
+ this.contextApi = createPluginContext(pluginId, scope);
27
+ this.context = this.contextApi.context;
28
+
29
+ this._unsubscribers = [];
30
+ }
31
+
32
+ /**
33
+ * @param {Pano} pano
34
+ */
35
+ onLoad(pano) {}
36
+ onUnload() {}
37
+
38
+ /** plugin context helper */
39
+ setContext(partial) {
40
+ this.contextApi.set(partial);
41
+ }
42
+
43
+ /** internal cleanup */
44
+ __destroy() {
45
+ this._unsubscribers.forEach((fn) => fn());
46
+ this.contextApi.destroy?.();
47
+ this.onUnload();
48
+ }
49
+ }
@@ -0,0 +1,21 @@
1
+ import { getPanoContext } from '../internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const components = panoContext.context.components;
5
+
6
+ export const PageActions = components.PageActions;
7
+ export const PageLoader = components.PageLoader;
8
+ export const PageNavItem = components.PageNavItem;
9
+ export const PageNav = components.PageNav;
10
+ export const Pagination = components.Pagination;
11
+ export const PageLoading = components.PageLoading;
12
+ export const Toast = components.Toast;
13
+ export const CardFilters = components.CardFilters;
14
+ export const CardFiltersItem = components.CardFiltersItem;
15
+ export const CardHeader = components.CardHeader;
16
+ export const CardMenu = components.CardMenu;
17
+ export const CardMenuItem = components.CardMenuItem;
18
+ export const Date = components.Date;
19
+ export const NoContent = components.NoContent;
20
+ export const Editor = components.Editor;
21
+ export const DragAndDropZone = components.DragAndDropZone;
package/src/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { getPanoContext } from './internal';
2
+
3
+ export * from './api/plugin.js';
4
+
5
+ export * from './utils/component.js';
@@ -0,0 +1 @@
1
+ export * from './pano-context.js';
@@ -0,0 +1,57 @@
1
+ const GLOBAL_KEY = '__PANO_CONTEXT__';
2
+
3
+ function getStore() {
4
+ if (!globalThis[GLOBAL_KEY]) {
5
+ globalThis[GLOBAL_KEY] = {
6
+ context: {},
7
+ listeners: [],
8
+ };
9
+ }
10
+ return globalThis[GLOBAL_KEY];
11
+ }
12
+
13
+ /**
14
+ * @typedef {import('../types.js').Pano} Pano
15
+ */
16
+
17
+ /**
18
+ * @param {Partial<Pano>} partial
19
+ */
20
+ export function setPanoContext(partial) {
21
+ const store = getStore();
22
+
23
+ if (typeof partial !== 'object' || partial === null) {
24
+ console.warn('[PanoSDK] setPanoContext expects an object');
25
+ return;
26
+ }
27
+
28
+ Object.assign(store.context, partial);
29
+
30
+ store.listeners.forEach((fn) => {
31
+ try {
32
+ fn(store.context);
33
+ } catch (e) {
34
+ console.error('[PanoSDK] listener error', e);
35
+ }
36
+ });
37
+ }
38
+
39
+ /**
40
+ * @returns {{ context: Pano, subscribe: (fn: (ctx: Pano) => void) => () => void }}
41
+ */
42
+ export function getPanoContext() {
43
+ const store = getStore();
44
+
45
+ return {
46
+ context: store.context,
47
+
48
+ subscribe(fn) {
49
+ store.listeners.push(fn);
50
+
51
+ // unsubscribe
52
+ return () => {
53
+ store.listeners = store.listeners.filter((l) => l !== fn);
54
+ };
55
+ },
56
+ };
57
+ }
package/src/svelte.js ADDED
@@ -0,0 +1,6 @@
1
+ import { getPanoContext } from './internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const { page, base, navigating, browser, goto, invalidate, invalidateAll, error } = panoContext.context;
5
+
6
+ export { page, base, navigating, browser, goto, invalidate, invalidateAll, error };
@@ -0,0 +1,9 @@
1
+ import { getPanoContext } from '../internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const toastStuff = panoContext.context.utils.toast;
5
+
6
+ const showToast = toastStuff.show;
7
+ const limitTitle = toastStuff.limitTitle;
8
+
9
+ export { showToast, limitTitle };
package/src/types.js ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @typedef {Object} Pano
3
+ * @property {boolean} isPanel
4
+ * @property {any} page - SvelteKit page store
5
+ * @property {string} base
6
+ * @property {any} navigating - SvelteKit navigating store
7
+ * @property {boolean} browser
8
+ * @property {Object} ui
9
+ * @property {Object} ui.page
10
+ * @property {function({path: string, component: any, layout?: any, resetLayout?: boolean}): void} ui.page.register
11
+ * @property {Object} ui.nav
12
+ * @property {Object} ui.nav.site
13
+ * @property {function(function(any[]): any[]): void} ui.nav.site.editNavLinks
14
+ * @property {Object} utils
15
+ * @property {Object} utils.api
16
+ * @property {any} utils.api.ApiUtil
17
+ * @property {function(Record<string, any>): string} utils.api.buildQueryParams
18
+ * @property {string} utils.api.NETWORK_ERROR
19
+ * @property {Object} utils.api.networkErrorBody
20
+ * @property {string} utils.api.networkErrorBody.result
21
+ * @property {string} utils.api.networkErrorBody.error
22
+ * @property {Object} utils.language
23
+ * @property {any} utils.language.init
24
+ * @property {any} utils.language._ - i18n store or function
25
+ * @property {Object} utils.tooltip
26
+ * @property {any} utils.tooltip.tooltip
27
+ * @property {any} utils.toast
28
+ * @property {Record<string, any>} components
29
+ * @property {Record<string, any>} variables
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} PanoPluginContext
34
+ * @property {any} context
35
+ * @property {function(any): void} set
36
+ * @property {function(function(any): void): function(): void} subscribe
37
+ * @property {function(): void} [destroy]
38
+ */
39
+
40
+ export {};
@@ -0,0 +1,14 @@
1
+ import { getPanoContext } from '../internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const apiStuff = panoContext.context.utils.api;
5
+
6
+ const ApiUtil = apiStuff.ApiUtil;
7
+
8
+ const NETWORK_ERROR = apiStuff.NETWORK_ERROR;
9
+ const networkErrorBody = apiStuff.networkErrorBody;
10
+ const buildQueryParams = apiStuff.buildQueryParams;
11
+
12
+ export { ApiUtil, NETWORK_ERROR, networkErrorBody, buildQueryParams };
13
+
14
+ export default ApiUtil;
@@ -0,0 +1,8 @@
1
+ import { getPanoContext } from "../internal/index.js";
2
+
3
+ const panoContext = getPanoContext();
4
+ const authStuff = panoContext.context.utils.auth;
5
+
6
+ const hasPermission = authStuff.hasPermission;
7
+
8
+ export { hasPermission };
@@ -0,0 +1,22 @@
1
+ import { hydrate, mount, unmount } from "svelte";
2
+
3
+ /**
4
+ * Wraps a dynamic component import to include the correct Svelte runtime mount/unmount methods.
5
+ * This bridges the gap between Host and Plugin runtimes.
6
+ *
7
+ * @param {() => Promise<any>} importer - Dynamic import function
8
+ * @returns {() => Promise<any>} - Wrapped importer
9
+ */
10
+ export function viewComponent(importer) {
11
+ const wrapper = async () => {
12
+ const module = await importer();
13
+ return {
14
+ ...module,
15
+ mount: (options) => mount(module.default, options),
16
+ unmount: (instance) => unmount(instance),
17
+ hydrate: (options) => hydrate(module.default, options),
18
+ };
19
+ };
20
+ wrapper._importer = importer;
21
+ return wrapper;
22
+ }
@@ -0,0 +1,26 @@
1
+ import { getPanoContext } from '../internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const languageStuff = panoContext.context.utils.language;
5
+
6
+ const languageLoading = languageStuff.languageLoading;
7
+ const currentLanguage = languageStuff.currentLanguage;
8
+ const Languages = languageStuff.Languages;
9
+ const init = languageStuff.init;
10
+ const getAcceptedLanguage = languageStuff.getAcceptedLanguage;
11
+ const loadLanguage = languageStuff.loadLanguage;
12
+ const changeLanguage = languageStuff.changeLanguage;
13
+ const getLanguageByLocale = languageStuff.getLanguageByLocale;
14
+ const _ = languageStuff._;
15
+
16
+ export {
17
+ languageLoading,
18
+ currentLanguage,
19
+ Languages,
20
+ init,
21
+ getAcceptedLanguage,
22
+ loadLanguage,
23
+ changeLanguage,
24
+ getLanguageByLocale,
25
+ _,
26
+ };
@@ -0,0 +1,8 @@
1
+ import { getPanoContext } from '../internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const textStuff = panoContext.context.utils.text;
5
+
6
+ const copy = textStuff.copy;
7
+
8
+ export { copy };
@@ -0,0 +1,10 @@
1
+ import { getPanoContext } from '../internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const tooltipStuff = panoContext.context.utils.tooltip;
5
+
6
+ const tooltip = tooltipStuff.tooltip;
7
+
8
+ export { tooltip };
9
+
10
+ export default tooltip;
@@ -0,0 +1,36 @@
1
+ import { getPanoContext } from './internal/index.js';
2
+
3
+ const panoContext = getPanoContext();
4
+ const variableStuff = panoContext.context.variables;
5
+
6
+ const API_URL = variableStuff.API_URL;
7
+ const UI_URL = variableStuff.UI_URL;
8
+ const PANEL_URL = variableStuff.PANEL_URL;
9
+ const SETUP_URL = variableStuff.SETUP_URL;
10
+ const PANO_WEBSITE_URL = variableStuff.PANO_WEBSITE_URL;
11
+ const PANO_WEBSITE_API_URL = variableStuff.PANO_WEBSITE_API_URL;
12
+ const PRERELEASE = variableStuff.PRERELEASE;
13
+ const COOKIE_PREFIX = variableStuff.COOKIE_PREFIX;
14
+ const CSRF_TOKEN_COOKIE_NAME = variableStuff.CSRF_TOKEN_COOKIE_NAME;
15
+ const JWT_COOKIE_NAME = variableStuff.JWT_COOKIE_NAME;
16
+ const CSRF_HEADER = variableStuff.CSRF_HEADER;
17
+ const updateApiUrl = variableStuff.updateApiUrl;
18
+ const updatePanoWebsiteUrl = variableStuff.updatePanoWebsiteUrl;
19
+ const updatePanoWebsiteApiUrl = variableStuff.updatePanoWebsiteApiUrl;
20
+
21
+ export {
22
+ API_URL,
23
+ UI_URL,
24
+ PANEL_URL,
25
+ SETUP_URL,
26
+ PANO_WEBSITE_URL,
27
+ PANO_WEBSITE_API_URL,
28
+ PRERELEASE,
29
+ COOKIE_PREFIX,
30
+ CSRF_TOKEN_COOKIE_NAME,
31
+ JWT_COOKIE_NAME,
32
+ CSRF_HEADER,
33
+ updateApiUrl,
34
+ updatePanoWebsiteUrl,
35
+ updatePanoWebsiteApiUrl,
36
+ };