Skip to content

Commit

Permalink
wip: split into multiple exports
Browse files Browse the repository at this point in the history
  • Loading branch information
idleberg committed Dec 6, 2024
1 parent 4efc4e5 commit 90e37c1
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 15 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@
### Import

```ts
import { createStore } from 'svelte-crossorigin-store';
import { createWritableStore } from 'svelte-crossorigin-store/iframe';

const store = createStore('Hello, world');
const store = createWritableStore('Hello, world');
const unsubscribe = store.subscribe(value => console.log('State updated:', value));
```

Or, in your Svelte component:

```svelte
<script>
import { createStore } from 'svelte-crossorigin-store';
import { createWritableStore } from 'svelte-crossorigin-store/iframe';
const store = createStore('Hello, world');
const store = createWritableStore('Hello, world');
</script>
<p>Current State: {$store}</p>
Expand All @@ -44,7 +44,7 @@ Or, in your Svelte component:

### API

#### `createStore`
#### `createWritableStore`

```ts
createStore<T>(initialValue?: T, {
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
"version": "0.1.1",
"description": "Share your Svelte store across origins, including iFrames",
"type": "module",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
"./iframe": {
"import": "./dist/iframe.js",
"types": "./dist/iframe.d.ts"
},
"./window": {
"import": "./dist/window.js",
"types": "./dist/window.d.ts"
}
},
"files": [
Expand Down
9 changes: 5 additions & 4 deletions src/index.ts → src/iframe.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import { writable, type Invalidator, type Subscriber, type Writable } from 'svelte/store';

type Options = {
Expand All @@ -22,7 +23,7 @@ type Options = {
* });
*```
*/
export function createStore<T>(initialValue: T, {
export function createWritableStore<T>(initialValue: T, {
allowedOrigins = ['*'],
id = 'svelte-crossorigin-store:message',
iframeSelector = 'iframe',
Expand All @@ -47,14 +48,13 @@ export function createStore<T>(initialValue: T, {
};
};

const _postMessageToManyOrigins = (target: HTMLIFrameElement['contentWindow'] | Window, value: any) => {
const _postMessageToManyOrigins = (target: HTMLIFrameElement['contentWindow'], value: any) => {
allowedOrigins.forEach(origin => {
target?.postMessage({ id, value }, origin);
});
}

store.subscribe(value => {
_postMessageToManyOrigins(window, value);

if (window.self === window.top) {
const iframes = document.querySelectorAll(iframeSelector) as NodeListOf<HTMLIFrameElement>;
Expand All @@ -63,7 +63,8 @@ export function createStore<T>(initialValue: T, {
_postMessageToManyOrigins(iframe.contentWindow, value)
});
} else {
_postMessageToManyOrigins(window.parent, value)
_postMessageToManyOrigins(window.parent, value);
return;
}

if (typeof onChange === 'function') {
Expand Down
66 changes: 66 additions & 0 deletions src/window.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { writable, type Invalidator, type Subscriber, type Writable } from 'svelte/store';

type Options = {
allowedOrigins?: string[];
id?: string;
onChange?: (value: any) => void;
};

/**
* Creates a writable Svelte store.
* @param initialValue
* @param options
* @returns
* @example
* ```ts
* createStore({
* allowedOrigins = ['*'],
* id = 'svelte-crossorigin-store:message',
* onChange = undefined,
* });
*```
*/
export function createWritableStore<T>(initialValue: T, {
allowedOrigins = ['*'],
id = 'svelte-crossorigin-store:message',
onChange = undefined,
}: Options = {}): Writable<T> {
const store = writable<T>(initialValue);
const { subscribe, set, update } = store;

const onMessage = (event: MessageEvent) => {
if ((allowedOrigins.includes(event.origin) || allowedOrigins.includes('*')) && event.data.id === id) {
set(event.data.value);
}
};

const _sharedSubscribe = (run: Subscriber<any>, invalidate: Invalidator<any> = () => { }) => {
subscribe(run, invalidate);

window.addEventListener('message', onMessage);

return () => {
window.removeEventListener('message', onMessage);
};
};

const _postMessageToManyOrigins = (target: Window, value: any) => {
allowedOrigins.forEach(origin => {
target?.postMessage({ id, value }, origin);
});
}

store.subscribe(value => {
_postMessageToManyOrigins(window, value);

if (typeof onChange === 'function') {
onChange(value);
}
});

return {
subscribe: _sharedSubscribe,
set,
update,
};
}
5 changes: 4 additions & 1 deletion tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ export default defineConfig((options) => {
target: 'esnext',
clean: true,
dts: !options.watch,
entry: ['src/index.ts'],
entry: [
'src/iframe.ts',
'src/window.ts',
],
format: 'esm',
minify: !options.watch,
treeshake: 'recommended'
Expand Down

0 comments on commit 90e37c1

Please sign in to comment.