@pulsesync/addon-sdk 0.1.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/README.md +119 -0
- package/dist/defineAddon.d.ts +4 -0
- package/dist/defineAddon.d.ts.map +1 -0
- package/dist/defineAddon.js +49 -0
- package/dist/defineAddon.js.map +1 -0
- package/dist/globals.d.ts +9 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +2 -0
- package/dist/globals.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/settings.d.ts +39 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +68 -0
- package/dist/settings.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/vite.d.ts +31 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +98 -0
- package/dist/vite.js.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# PulseSync Addon SDK
|
|
2
|
+
|
|
3
|
+
Публичный TypeScript/React SDK для аддонов, которые запускаются через PulseSync WebHost.
|
|
4
|
+
|
|
5
|
+
WebHost владеет единственным React root и предоставляет аддонам React `19.2.4`. Аддон экспортирует компоненты и не вызывает `createRoot()` самостоятельно.
|
|
6
|
+
|
|
7
|
+
## Установка
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @pulsesync/addon-sdk react@19.2.4
|
|
11
|
+
npm install -D vite @vitejs/plugin-react typescript @types/react
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Обычный компонент
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { defineAddon } from '@pulsesync/addon-sdk'
|
|
18
|
+
|
|
19
|
+
function App() {
|
|
20
|
+
return <div>PulseSync addon</div>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default defineAddon({
|
|
24
|
+
id: 'example-addon',
|
|
25
|
+
name: 'Example Addon',
|
|
26
|
+
component: App,
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Стандартные точки интерфейса
|
|
31
|
+
|
|
32
|
+
Имена slots задаёт WebHost. Аддон только отдаёт React-компонент для нужной точки.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
export default defineAddon({
|
|
36
|
+
id: 'player-actions',
|
|
37
|
+
slots: {
|
|
38
|
+
playerBarButton: PlayerButton,
|
|
39
|
+
contextMenuActions: ContextMenuActions,
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Произвольная точка
|
|
45
|
+
|
|
46
|
+
Если стандартного slot нет, автор может указать DOM-цель самостоятельно.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
export default defineAddon({
|
|
50
|
+
id: 'custom-target',
|
|
51
|
+
mounts: [
|
|
52
|
+
{
|
|
53
|
+
target: '[data-test-id="PLAYERBAR_DESKTOP"]',
|
|
54
|
+
component: PlayerButton,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`target` также принимает `Element`, функцию `() => Element | null`, `{ selector }` или `{ slot }`.
|
|
61
|
+
|
|
62
|
+
## Lifecycle
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
export default defineAddon({
|
|
66
|
+
id: 'lifecycle-example',
|
|
67
|
+
start(api) {
|
|
68
|
+
api.logger.info('Started')
|
|
69
|
+
return () => api.logger.info('Start cleanup')
|
|
70
|
+
},
|
|
71
|
+
stop(api) {
|
|
72
|
+
api.logger.info('Stopped')
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Настройки
|
|
78
|
+
|
|
79
|
+
Схема живёт рядом с кодом аддона и остаётся типизированной:
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { defineSettings, type PulseSyncAddonComponentProps } from '@pulsesync/addon-sdk'
|
|
83
|
+
|
|
84
|
+
export const settings = defineSettings({
|
|
85
|
+
enabled: {
|
|
86
|
+
type: 'boolean',
|
|
87
|
+
name: 'Включить аддон',
|
|
88
|
+
default: true,
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
function App({ api }: PulseSyncAddonComponentProps) {
|
|
93
|
+
const { enabled } = settings.use(api)
|
|
94
|
+
return enabled ? <div>PulseSync addon</div> : null
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Передай `settings` в `pulseSyncAddon({ manifest, settings })`. Сборщик запишет схему в `metadata.json`; отдельный `handleEvents.json` для WebHost-аддона не нужен.
|
|
99
|
+
|
|
100
|
+
## Vite
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import react from '@vitejs/plugin-react'
|
|
104
|
+
import { defineConfig } from 'vite'
|
|
105
|
+
import { defineAddonManifest, pulseSyncAddon } from '@pulsesync/addon-sdk/vite'
|
|
106
|
+
|
|
107
|
+
const manifest = defineAddonManifest({
|
|
108
|
+
id: 'example-addon',
|
|
109
|
+
directoryName: 'example-addon',
|
|
110
|
+
name: 'Example Addon',
|
|
111
|
+
version: '0.1.0',
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
export default defineConfig({
|
|
115
|
+
plugins: [react(), pulseSyncAddon({ manifest })],
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Плагин собирает `script.js`, `script.css` и `metadata.json`, помечает аддон как `web-addon`, исключает React из бандла и запрещает импорт `react-dom`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineAddon.d.ts","sourceRoot":"","sources":["../src/defineAddon.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGR,wBAAwB,EAExB,qBAAqB,EAExB,MAAM,YAAY,CAAA;AAkCnB,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,wBAAwB,CAcpF;eAEc,WAAW"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PULSESYNC_WEB_HOST_API_VERSION } from './version.js';
|
|
2
|
+
function normalizeId(id) {
|
|
3
|
+
const normalizedId = String(id ?? '').trim();
|
|
4
|
+
if (!normalizedId)
|
|
5
|
+
throw new TypeError('PulseSync addon id is required');
|
|
6
|
+
return normalizedId;
|
|
7
|
+
}
|
|
8
|
+
function createActivation(options) {
|
|
9
|
+
if (!options.start && !options.stop)
|
|
10
|
+
return undefined;
|
|
11
|
+
return (api) => {
|
|
12
|
+
const cleanup = options.start?.(api);
|
|
13
|
+
let active = true;
|
|
14
|
+
return () => {
|
|
15
|
+
if (!active)
|
|
16
|
+
return;
|
|
17
|
+
active = false;
|
|
18
|
+
try {
|
|
19
|
+
if (typeof cleanup === 'function')
|
|
20
|
+
cleanup();
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
options.stop?.(api);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function enqueue(factory) {
|
|
29
|
+
if (typeof window === 'undefined')
|
|
30
|
+
return;
|
|
31
|
+
const queue = (window.__PULSESYNC_ADDON_QUEUE__ ??= []);
|
|
32
|
+
queue.push(factory);
|
|
33
|
+
}
|
|
34
|
+
export function defineAddon(options) {
|
|
35
|
+
const activate = createActivation(options);
|
|
36
|
+
const definition = Object.freeze({
|
|
37
|
+
id: normalizeId(options.id),
|
|
38
|
+
apiVersion: PULSESYNC_WEB_HOST_API_VERSION,
|
|
39
|
+
...(options.name ? { name: options.name } : {}),
|
|
40
|
+
...(options.component ? { component: options.component } : {}),
|
|
41
|
+
...(options.slots ? { slots: Object.freeze({ ...options.slots }) } : {}),
|
|
42
|
+
...(options.mounts ? { mounts: Object.freeze([...options.mounts]) } : {}),
|
|
43
|
+
...(activate ? { activate } : {}),
|
|
44
|
+
});
|
|
45
|
+
enqueue((_host) => definition);
|
|
46
|
+
return definition;
|
|
47
|
+
}
|
|
48
|
+
export default defineAddon;
|
|
49
|
+
//# sourceMappingURL=defineAddon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineAddon.js","sourceRoot":"","sources":["../src/defineAddon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAA;AAU7D,SAAS,WAAW,CAAC,EAAU;IAC3B,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC5C,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAA;IACxE,OAAO,YAAY,CAAA;AACvB,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA8B;IACpD,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAErD,OAAO,CAAC,GAAsB,EAAyB,EAAE;QACrD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;QACpC,IAAI,MAAM,GAAG,IAAI,CAAA;QAEjB,OAAO,GAAG,EAAE;YACR,IAAI,CAAC,MAAM;gBAAE,OAAM;YACnB,MAAM,GAAG,KAAK,CAAA;YAEd,IAAI,CAAC;gBACD,IAAI,OAAO,OAAO,KAAK,UAAU;oBAAE,OAAO,EAAE,CAAA;YAChD,CAAC;oBAAS,CAAC;gBACP,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAA;YACvB,CAAC;QACL,CAAC,CAAA;IACL,CAAC,CAAA;AACL,CAAC;AAED,SAAS,OAAO,CAAC,OAA8B;IAC3C,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAM;IACzC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAA;IACvD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAA8B;IACtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,UAAU,GAA6B,MAAM,CAAC,MAAM,CAAC;QACvD,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,UAAU,EAAE,8BAA8B;QAC1C,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpC,CAAC,CAAA;IAEF,OAAO,CAAC,CAAC,KAA0B,EAAE,EAAE,CAAC,UAAU,CAAC,CAAA;IACnD,OAAO,UAAU,CAAA;AACrB,CAAC;AAED,eAAe,WAAW,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PulseSyncAddonFactory, PulseSyncWebHostApi } from './types.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
__PULSESYNC_WEB_HOST__?: PulseSyncWebHostApi;
|
|
5
|
+
__PULSESYNC_ADDON_QUEUE__?: PulseSyncAddonFactory[];
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=globals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAE5E,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,sBAAsB,CAAC,EAAE,mBAAmB,CAAA;QAC5C,yBAAyB,CAAC,EAAE,qBAAqB,EAAE,CAAA;KACtD;CACJ;AAED,OAAO,EAAE,CAAA"}
|
package/dist/globals.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import './globals.js';
|
|
2
|
+
export { default, defineAddon } from './defineAddon.js';
|
|
3
|
+
export { defineSettings } from './settings.js';
|
|
4
|
+
export { PULSESYNC_WEB_HOST_API_VERSION } from './version.js';
|
|
5
|
+
export type { AddonSettings, AddonSettingsStore, AddonSettingValue, PulseSyncApi } from '@pulsesync/yamusic-types';
|
|
6
|
+
export type { PulseSyncAddonApi, PulseSyncAddonCleanup, PulseSyncAddonComponent, PulseSyncAddonComponentProps, PulseSyncAddonDefinition, PulseSyncAddonFactory, PulseSyncAddonLogger, PulseSyncAddonMount, PulseSyncAddonMountTarget, PulseSyncAddonOptions, PulseSyncWebHostApi, } from './types.js';
|
|
7
|
+
export type { DefineSettingsOptions, InferPulseSyncSettings, PulseSyncSetting, PulseSyncSettingsConfig, PulseSyncSettingsDefinition, PulseSyncSettingsSchema, } from './settings.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAA;AAErB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAA;AAC7D,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAClH,YAAY,EACR,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,YAAY,CAAA;AACnB,YAAY,EACR,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,GAC1B,MAAM,eAAe,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAA;AAErB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PulseSyncAddonApi } from './types.js';
|
|
2
|
+
type SettingBase<TType extends string, TValue> = {
|
|
3
|
+
readonly type: TType;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly description?: string;
|
|
6
|
+
readonly default: TValue;
|
|
7
|
+
};
|
|
8
|
+
export type PulseSyncSetting = SettingBase<'boolean', boolean> | SettingBase<'color', string> | SettingBase<'text', string> | SettingBase<'file', string> | (SettingBase<'number', number> & {
|
|
9
|
+
readonly min: number;
|
|
10
|
+
readonly max: number;
|
|
11
|
+
readonly step?: number;
|
|
12
|
+
}) | (SettingBase<'select', string | number> & {
|
|
13
|
+
readonly options: readonly {
|
|
14
|
+
readonly label: string;
|
|
15
|
+
readonly value: string | number;
|
|
16
|
+
}[];
|
|
17
|
+
});
|
|
18
|
+
export type PulseSyncSettingsSchema = Readonly<Record<string, PulseSyncSetting>>;
|
|
19
|
+
export type InferPulseSyncSettings<TSchema extends PulseSyncSettingsSchema> = {
|
|
20
|
+
readonly [TKey in keyof TSchema]: TSchema[TKey]['default'];
|
|
21
|
+
};
|
|
22
|
+
export type PulseSyncSettingsConfig = {
|
|
23
|
+
readonly sections: readonly {
|
|
24
|
+
readonly title: string;
|
|
25
|
+
readonly items: readonly Record<string, unknown>[];
|
|
26
|
+
}[];
|
|
27
|
+
};
|
|
28
|
+
export type PulseSyncSettingsDefinition<TSchema extends PulseSyncSettingsSchema = PulseSyncSettingsSchema> = {
|
|
29
|
+
readonly schema: TSchema;
|
|
30
|
+
readonly defaults: InferPulseSyncSettings<TSchema>;
|
|
31
|
+
use: (api: PulseSyncAddonApi) => InferPulseSyncSettings<TSchema>;
|
|
32
|
+
toConfig: () => PulseSyncSettingsConfig;
|
|
33
|
+
};
|
|
34
|
+
export type DefineSettingsOptions = {
|
|
35
|
+
readonly title?: string;
|
|
36
|
+
};
|
|
37
|
+
export declare function defineSettings<const TSchema extends PulseSyncSettingsSchema>(schema: TSchema, options?: DefineSettingsOptions): PulseSyncSettingsDefinition<TSchema>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,KAAK,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,IAAI;IAC7C,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,gBAAgB,GACtB,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,GAC/B,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,GAC5B,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACzB,CAAC,GACF,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS;QACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAClC,EAAE,CAAA;CACN,CAAC,CAAA;AAER,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAA;AAEhF,MAAM,MAAM,sBAAsB,CAAC,OAAO,SAAS,uBAAuB,IAAI;IAC1E,QAAQ,EAAE,IAAI,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;CAC7D,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KACrD,EAAE,CAAA;CACN,CAAA;AAED,MAAM,MAAM,2BAA2B,CAAC,OAAO,SAAS,uBAAuB,GAAG,uBAAuB,IAAI;IACzG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAClD,GAAG,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAChE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;CAC1C,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAoDD,wBAAgB,cAAc,CAAC,KAAK,CAAC,OAAO,SAAS,uBAAuB,EACxE,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,qBAA0B,GACpC,2BAA2B,CAAC,OAAO,CAAC,CA6BtC"}
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
function readSettingValue(entry, fallback) {
|
|
3
|
+
if (entry && typeof entry === 'object' && !Array.isArray(entry)) {
|
|
4
|
+
const setting = entry;
|
|
5
|
+
if (typeof setting.value !== 'undefined')
|
|
6
|
+
return setting.value;
|
|
7
|
+
if (typeof setting.default !== 'undefined')
|
|
8
|
+
return setting.default;
|
|
9
|
+
}
|
|
10
|
+
return typeof entry === 'undefined' ? fallback : entry;
|
|
11
|
+
}
|
|
12
|
+
function createDefaults(schema) {
|
|
13
|
+
return Object.fromEntries(Object.entries(schema).map(([id, setting]) => [id, setting.default]));
|
|
14
|
+
}
|
|
15
|
+
function resolveValues(schema, current) {
|
|
16
|
+
return Object.fromEntries(Object.entries(schema).map(([id, setting]) => [id, readSettingValue(current[id], setting.default)]));
|
|
17
|
+
}
|
|
18
|
+
function settingToConfig(id, setting) {
|
|
19
|
+
const common = {
|
|
20
|
+
id,
|
|
21
|
+
name: setting.name,
|
|
22
|
+
...(setting.description ? { description: setting.description } : {}),
|
|
23
|
+
value: setting.default,
|
|
24
|
+
defaultValue: setting.default,
|
|
25
|
+
};
|
|
26
|
+
switch (setting.type) {
|
|
27
|
+
case 'boolean':
|
|
28
|
+
return { ...common, type: 'button' };
|
|
29
|
+
case 'number':
|
|
30
|
+
return { ...common, type: 'slider', min: setting.min, max: setting.max, step: setting.step ?? 1 };
|
|
31
|
+
case 'select':
|
|
32
|
+
return {
|
|
33
|
+
...common,
|
|
34
|
+
type: 'selector',
|
|
35
|
+
options: Object.fromEntries(setting.options.map(option => [String(option.value), { event: String(option.value), name: option.label }])),
|
|
36
|
+
};
|
|
37
|
+
default:
|
|
38
|
+
return { ...common, type: setting.type };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function defineSettings(schema, options = {}) {
|
|
42
|
+
const defaults = Object.freeze(createDefaults(schema));
|
|
43
|
+
const frozenSchema = Object.freeze({ ...schema });
|
|
44
|
+
return Object.freeze({
|
|
45
|
+
schema: frozenSchema,
|
|
46
|
+
defaults,
|
|
47
|
+
use(api) {
|
|
48
|
+
const [values, setValues] = useState(defaults);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const store = api.pulsesyncApi?.getSettings(api.addonId);
|
|
51
|
+
if (!store)
|
|
52
|
+
return;
|
|
53
|
+
setValues(resolveValues(frozenSchema, store.getCurrent()));
|
|
54
|
+
return store.onChange(current => setValues(resolveValues(frozenSchema, current)));
|
|
55
|
+
}, [api]);
|
|
56
|
+
return values;
|
|
57
|
+
},
|
|
58
|
+
toConfig: () => ({
|
|
59
|
+
sections: [
|
|
60
|
+
{
|
|
61
|
+
title: options.title ?? 'Settings',
|
|
62
|
+
items: Object.entries(frozenSchema).map(([id, setting]) => settingToConfig(id, setting)),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
import type { PulseSyncApi } from '@pulsesync/yamusic-types';
|
|
3
|
+
export type PulseSyncAddonCleanup = () => void;
|
|
4
|
+
export type PulseSyncAddonLogger = {
|
|
5
|
+
info: (...args: unknown[]) => void;
|
|
6
|
+
warn: (...args: unknown[]) => void;
|
|
7
|
+
error: (...args: unknown[]) => void;
|
|
8
|
+
};
|
|
9
|
+
export type PulseSyncAddonApi = {
|
|
10
|
+
readonly addonId: string;
|
|
11
|
+
readonly pulsesyncApi: PulseSyncApi | undefined;
|
|
12
|
+
readonly logger: PulseSyncAddonLogger;
|
|
13
|
+
};
|
|
14
|
+
export type PulseSyncAddonComponentProps = {
|
|
15
|
+
readonly addonId: string;
|
|
16
|
+
readonly api: PulseSyncAddonApi;
|
|
17
|
+
};
|
|
18
|
+
export type PulseSyncAddonComponent = ComponentType<PulseSyncAddonComponentProps>;
|
|
19
|
+
export type PulseSyncAddonMountTarget = Element | string | (() => Element | null) | {
|
|
20
|
+
readonly selector: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly slot: string;
|
|
23
|
+
};
|
|
24
|
+
export type PulseSyncAddonMount = {
|
|
25
|
+
readonly target: PulseSyncAddonMountTarget;
|
|
26
|
+
readonly component: PulseSyncAddonComponent;
|
|
27
|
+
};
|
|
28
|
+
export type PulseSyncAddonOptions = {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly name?: string;
|
|
31
|
+
readonly component?: PulseSyncAddonComponent;
|
|
32
|
+
readonly slots?: Readonly<Record<string, PulseSyncAddonComponent>>;
|
|
33
|
+
readonly mounts?: readonly PulseSyncAddonMount[];
|
|
34
|
+
readonly start?: (api: PulseSyncAddonApi) => void | PulseSyncAddonCleanup;
|
|
35
|
+
readonly stop?: (api: PulseSyncAddonApi) => void;
|
|
36
|
+
};
|
|
37
|
+
export type PulseSyncAddonDefinition = Omit<PulseSyncAddonOptions, 'start' | 'stop'> & {
|
|
38
|
+
readonly apiVersion: number;
|
|
39
|
+
readonly activate?: (api: PulseSyncAddonApi) => void | PulseSyncAddonCleanup;
|
|
40
|
+
};
|
|
41
|
+
export type PulseSyncAddonFactory = (host: PulseSyncWebHostApi) => void | PulseSyncAddonDefinition | Promise<void | PulseSyncAddonDefinition>;
|
|
42
|
+
export type PulseSyncWebHostApi = {
|
|
43
|
+
readonly apiVersion: number;
|
|
44
|
+
readonly React: typeof import('react');
|
|
45
|
+
readonly jsxRuntime: typeof import('react/jsx-runtime');
|
|
46
|
+
readonly jsxDevRuntime?: typeof import('react/jsx-dev-runtime');
|
|
47
|
+
installAddon: (factory: PulseSyncAddonFactory) => Promise<PulseSyncAddonCleanup | undefined>;
|
|
48
|
+
registerAddon: (definition: PulseSyncAddonDefinition) => PulseSyncAddonCleanup;
|
|
49
|
+
unregisterAddon: (addonId: string) => boolean;
|
|
50
|
+
getPulseSyncApi: () => PulseSyncApi | undefined;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B,EAAG,CAAU,CAAA"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAU,CAAA"}
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import type { PulseSyncSettingsDefinition } from './settings.js';
|
|
3
|
+
export type PulseSyncAddonManifest = {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly directoryName: string;
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly description?: string;
|
|
8
|
+
readonly version: string;
|
|
9
|
+
readonly author?: string | readonly string[];
|
|
10
|
+
readonly image?: string;
|
|
11
|
+
readonly banner?: string;
|
|
12
|
+
readonly libraryLogo?: string;
|
|
13
|
+
readonly tags?: readonly string[];
|
|
14
|
+
readonly dependencies?: readonly string[];
|
|
15
|
+
readonly allowedUrls?: readonly string[];
|
|
16
|
+
readonly supportedVersions?: readonly string[];
|
|
17
|
+
};
|
|
18
|
+
export type PulseSyncAddonViteOptions = {
|
|
19
|
+
readonly manifest: PulseSyncAddonManifest;
|
|
20
|
+
readonly settings?: PulseSyncSettingsDefinition;
|
|
21
|
+
readonly entry?: string;
|
|
22
|
+
readonly staticDir?: string | false;
|
|
23
|
+
readonly outDir?: string;
|
|
24
|
+
readonly globalName?: string;
|
|
25
|
+
readonly minify?: boolean | 'esbuild' | 'oxc' | 'terser';
|
|
26
|
+
readonly sourcemap?: boolean;
|
|
27
|
+
readonly target?: string;
|
|
28
|
+
};
|
|
29
|
+
export declare function defineAddonManifest<const T extends PulseSyncAddonManifest>(manifest: T): T;
|
|
30
|
+
export declare function pulseSyncAddon(options: PulseSyncAddonViteOptions): Plugin;
|
|
31
|
+
//# sourceMappingURL=vite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAA8B,MAAM,MAAM,CAAA;AAE9D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAEhE,MAAM,MAAM,sBAAsB,GAAG;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACjD,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAA;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,2BAA2B,CAAA;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAA;IACxD,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,CAAC,SAAS,sBAAsB,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAE1F;AA2BD,wBAAgB,cAAc,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CA8EzE"}
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function defineAddonManifest(manifest) {
|
|
4
|
+
return manifest;
|
|
5
|
+
}
|
|
6
|
+
function cleanManifestValue(value) {
|
|
7
|
+
if (Array.isArray(value))
|
|
8
|
+
return value.map(item => String(item).trim()).filter(Boolean);
|
|
9
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
10
|
+
}
|
|
11
|
+
function createMetadata(manifest) {
|
|
12
|
+
return {
|
|
13
|
+
id: manifest.id,
|
|
14
|
+
name: manifest.name,
|
|
15
|
+
description: manifest.description ?? '',
|
|
16
|
+
version: manifest.version,
|
|
17
|
+
author: cleanManifestValue(manifest.author),
|
|
18
|
+
type: 'web-addon',
|
|
19
|
+
image: manifest.image ?? '',
|
|
20
|
+
banner: manifest.banner ?? '',
|
|
21
|
+
libraryLogo: manifest.libraryLogo ?? '',
|
|
22
|
+
css: 'script.css',
|
|
23
|
+
script: 'script.js',
|
|
24
|
+
tags: manifest.tags ?? [],
|
|
25
|
+
dependencies: manifest.dependencies ?? [],
|
|
26
|
+
allowedUrls: manifest.allowedUrls ?? [],
|
|
27
|
+
supportedVersions: manifest.supportedVersions ?? [],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function pulseSyncAddon(options) {
|
|
31
|
+
let resolvedConfig;
|
|
32
|
+
let outputDirectory = '';
|
|
33
|
+
return {
|
|
34
|
+
name: 'pulsesync-addon',
|
|
35
|
+
enforce: 'pre',
|
|
36
|
+
config(currentConfig) {
|
|
37
|
+
const root = path.resolve(currentConfig.root ?? process.cwd());
|
|
38
|
+
outputDirectory = options.outDir
|
|
39
|
+
? path.resolve(root, options.outDir)
|
|
40
|
+
: path.resolve(root, 'dist', options.manifest.directoryName);
|
|
41
|
+
return {
|
|
42
|
+
build: {
|
|
43
|
+
target: options.target ?? 'chrome140',
|
|
44
|
+
outDir: outputDirectory,
|
|
45
|
+
emptyOutDir: true,
|
|
46
|
+
minify: options.minify ?? 'oxc',
|
|
47
|
+
sourcemap: options.sourcemap ?? false,
|
|
48
|
+
cssCodeSplit: false,
|
|
49
|
+
lib: {
|
|
50
|
+
entry: path.resolve(root, options.entry ?? 'src/main.tsx'),
|
|
51
|
+
formats: ['iife'],
|
|
52
|
+
name: options.globalName ?? 'PulseSyncAddon',
|
|
53
|
+
fileName: () => 'script.js',
|
|
54
|
+
cssFileName: 'script',
|
|
55
|
+
},
|
|
56
|
+
rollupOptions: {
|
|
57
|
+
external: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime'],
|
|
58
|
+
output: {
|
|
59
|
+
globals: {
|
|
60
|
+
react: 'window.__PULSESYNC_WEB_HOST__.React',
|
|
61
|
+
'react/jsx-runtime': 'window.__PULSESYNC_WEB_HOST__.jsxRuntime',
|
|
62
|
+
'react/jsx-dev-runtime': 'window.__PULSESYNC_WEB_HOST__.jsxDevRuntime',
|
|
63
|
+
},
|
|
64
|
+
assetFileNames: assetInfo => assetInfo.names.some(name => name.endsWith('.css')) ? '[name][extname]' : 'Assets/[name][extname]',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
configResolved(config) {
|
|
71
|
+
resolvedConfig = config;
|
|
72
|
+
outputDirectory ||= path.resolve(config.root, 'dist', options.manifest.directoryName);
|
|
73
|
+
},
|
|
74
|
+
resolveId(source) {
|
|
75
|
+
if (source === 'react-dom' || source.startsWith('react-dom/')) {
|
|
76
|
+
throw new Error('PulseSync WebHost owns the React root. Export components from defineAddon instead of importing react-dom.');
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
async closeBundle() {
|
|
80
|
+
await fs.mkdir(outputDirectory, { recursive: true });
|
|
81
|
+
if (options.staticDir !== false) {
|
|
82
|
+
const staticDirectory = path.resolve(resolvedConfig.root, options.staticDir ?? 'addon');
|
|
83
|
+
try {
|
|
84
|
+
await fs.cp(staticDirectory, outputDirectory, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error.code !== 'ENOENT')
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
await fs.writeFile(path.join(outputDirectory, 'metadata.json'), `${JSON.stringify({
|
|
92
|
+
...createMetadata(options.manifest),
|
|
93
|
+
...(options.settings ? { settings: options.settings.toConfig() } : {}),
|
|
94
|
+
}, null, 4)}\n`, 'utf8');
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=vite.js.map
|
package/dist/vite.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pulsesync/addon-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Public SDK for building PulseSync WebHost addons",
|
|
5
|
+
"license": "GPL-3.0-or-later",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./vite": {
|
|
15
|
+
"types": "./dist/vite.d.ts",
|
|
16
|
+
"import": "./dist/vite.js"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.json",
|
|
29
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
30
|
+
"lint": "oxlint src",
|
|
31
|
+
"pack:local": "npm run build && npm pack",
|
|
32
|
+
"prepublishOnly": "npm run check && npm run lint && npm run build"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@pulsesync/yamusic-types": "^0.0.1"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": "19.2.4",
|
|
39
|
+
"vite": "^8.2.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependenciesMeta": {
|
|
42
|
+
"vite": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "26.1.2",
|
|
48
|
+
"@types/react": "19.2.17",
|
|
49
|
+
"oxlint": "1.76.0",
|
|
50
|
+
"react": "19.2.4",
|
|
51
|
+
"typescript": "7.0.2",
|
|
52
|
+
"vite": "8.2.0"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=20"
|
|
56
|
+
},
|
|
57
|
+
"keywords": [
|
|
58
|
+
"pulsesync",
|
|
59
|
+
"addon",
|
|
60
|
+
"plugin",
|
|
61
|
+
"react",
|
|
62
|
+
"sdk"
|
|
63
|
+
]
|
|
64
|
+
}
|