@collagejs/svelte 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 +44 -0
- package/dist/Piece/Piece.svelte +154 -0
- package/dist/Piece/Piece.svelte.d.ts +108 -0
- package/dist/collageContext.d.ts +15 -0
- package/dist/collageContext.js +20 -0
- package/dist/collagejs/collage.svelte.d.ts +13 -0
- package/dist/collagejs/collage.svelte.js +75 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +10 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +1 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# <img src="https://raw.githubusercontent.com/collagejs/core/HEAD/src/logos/collagejs-48.svg" alt="CollageJS Logo" width="48" height="48" align="left"> @collagejs/svelte
|
|
2
|
+
|
|
3
|
+
> Svelte v5 integration for the CollageJS micro-frontend library
|
|
4
|
+
|
|
5
|
+
[Online Documentation](https://collagejs.dev)
|
|
6
|
+
|
|
7
|
+
This is the official Svelte component library for *CollageJS* used to:
|
|
8
|
+
|
|
9
|
+
1. Create *CollageJS* `CorePiece` objects out of Svelte components
|
|
10
|
+
2. Consume `CorePiece` objects (made with any framework or library) in Svelte v5 projects
|
|
11
|
+
|
|
12
|
+
## Creating Svelte-Based `CorePiece` Objects
|
|
13
|
+
|
|
14
|
+
Whenever we are creating a micro-frontend in Svelte v5 and wish for it to be used with *CollageJS*, we must create a `CorePiece` wrapper object for the Svelte component that is the root of our micro-frontend. Unless we wanted to take on this task ourselves, we use this package's `buildPiece()` function:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// mfe.ts (or whatever name you wish for the file)
|
|
18
|
+
import { buildPiece } from "@collagejs/svelte";
|
|
19
|
+
// The component to wrap. It usually is App.svelte.
|
|
20
|
+
import App from "./App.svelte";
|
|
21
|
+
|
|
22
|
+
export function myMfeFactory() {
|
|
23
|
+
return buildPiece(App /*, { options } */);
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> ✨ **Tip**: Repeat this process in the same or different file for any number of Svelte components that you wish to make available as independent micro-frontends. The sky is the limit.
|
|
28
|
+
|
|
29
|
+
## Consuming `CorePiece` Objects
|
|
30
|
+
|
|
31
|
+
We can mount *CollageJS* pieces created in any technology in Svelte projects by using the `<Piece>` component. This component requires that we pass the `CorePiece` object that we wish to mount. Any other properties given to `<Piece>` are forwarded to the mounted `CorePiece` object:
|
|
32
|
+
|
|
33
|
+
```svelte
|
|
34
|
+
<script lang="ts">
|
|
35
|
+
import { Piece, piece } from "@collagejs/svelte";
|
|
36
|
+
import { myMfeFactory } from "@my/bare-module-specifier";
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<Piece {...piece(myMfeFactory())} extra="yes" data={true} />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
1. We must use the `piece()` function to pass the `CorePiece` object.
|
|
43
|
+
2. The example uses the name of the factory function in the previous example, so we're mounting a Svelte MFE inside a Svelte project.
|
|
44
|
+
3. The `"@my/bare-module-specifier"` module name is the bare module specifier we assign to the micro-frontend in our root project's import map.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
const piecePropsSymbol = Symbol();
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Defines the special properties accepted by the `Piece` component. This type is to be used in conjunction with
|
|
6
|
+
* the `piece()` helper function to create the special property required by the `Piece` component.
|
|
7
|
+
*/
|
|
8
|
+
export type PieceProps<
|
|
9
|
+
TProps extends Record<string, any> = Record<string, any>,
|
|
10
|
+
> = {
|
|
11
|
+
/**
|
|
12
|
+
* The special property that contains the `CorePiece` instance to render, along with optional container
|
|
13
|
+
* properties.
|
|
14
|
+
*/
|
|
15
|
+
[piecePropsSymbol]: {
|
|
16
|
+
/**
|
|
17
|
+
* The `CorePiece` instance to render.
|
|
18
|
+
*/
|
|
19
|
+
piece: CorePiece<TProps>;
|
|
20
|
+
/**
|
|
21
|
+
* Optional HTML attributes to set on the container element that wraps the piece.
|
|
22
|
+
*/
|
|
23
|
+
containerProps?: HTMLAttributes<HTMLDivElement>;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Helper function to create the special property required by the `Piece` component. The result of this function
|
|
29
|
+
* is to be spread into the props of the `Piece` component.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```svelte
|
|
33
|
+
* <Piece {...piece(myPiece, { onfocusin: focusInHandler })} foo="bar" count={42} />
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @param piece The `CorePiece` instance to render.
|
|
37
|
+
* @param containerProps Optional HTML attributes to set on the container element that wraps the piece.
|
|
38
|
+
* @returns An object containing the special property to pass to the `Piece` component.
|
|
39
|
+
*/
|
|
40
|
+
export function piece<
|
|
41
|
+
TProps extends Record<string, any> = Record<string, any>,
|
|
42
|
+
>(
|
|
43
|
+
piece: CorePiece<TProps>,
|
|
44
|
+
containerProps?: HTMLAttributes<HTMLDivElement>,
|
|
45
|
+
) {
|
|
46
|
+
return {
|
|
47
|
+
[piecePropsSymbol]: {
|
|
48
|
+
piece,
|
|
49
|
+
containerProps,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<script
|
|
56
|
+
lang="ts"
|
|
57
|
+
generics="TProps extends Record<string, any> = Record<string, any>"
|
|
58
|
+
>
|
|
59
|
+
import { getCollageContext } from "../collageContext.js";
|
|
60
|
+
import {
|
|
61
|
+
mountPiece,
|
|
62
|
+
type CorePiece,
|
|
63
|
+
type MountedPiece,
|
|
64
|
+
type MountPiece,
|
|
65
|
+
} from "@collagejs/core";
|
|
66
|
+
import { onMount } from "svelte";
|
|
67
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
68
|
+
|
|
69
|
+
type Props = TProps & PieceProps<TProps>;
|
|
70
|
+
|
|
71
|
+
let { ...restProps }: Props = $props();
|
|
72
|
+
|
|
73
|
+
const { piece: corePiece, containerProps } = $derived(restProps[piecePropsSymbol]);
|
|
74
|
+
let containerEl: HTMLDivElement;
|
|
75
|
+
let firstRun = true;
|
|
76
|
+
const ctx = getCollageContext();
|
|
77
|
+
let mountedPiece: MountedPiece<TProps> | undefined;
|
|
78
|
+
|
|
79
|
+
onMount(() => {
|
|
80
|
+
const mountPieceFn =
|
|
81
|
+
(ctx?.mountPiece as MountPiece<TProps>) ?? mountPiece<TProps>;
|
|
82
|
+
const mountPromise = mountPieceFn(corePiece, containerEl, restProps).then((mp) => {
|
|
83
|
+
mountedPiece = mp;
|
|
84
|
+
});
|
|
85
|
+
return async () => {
|
|
86
|
+
await mountPromise;
|
|
87
|
+
await mountedPiece?.unmount();
|
|
88
|
+
mountedPiece = undefined;
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
$effect(() => {
|
|
93
|
+
// Must be the first line so the dependency on restProps is tracked.
|
|
94
|
+
const newProps = { ...restProps };
|
|
95
|
+
delete (newProps as any)[piecePropsSymbol];
|
|
96
|
+
if (firstRun) {
|
|
97
|
+
firstRun = false;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
mountedPiece?.update(newProps);
|
|
101
|
+
});
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<div bind:this={containerEl} {...containerProps}></div>
|
|
105
|
+
|
|
106
|
+
<style>
|
|
107
|
+
div {
|
|
108
|
+
display: contents;
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
111
|
+
<!--
|
|
112
|
+
@component
|
|
113
|
+
|
|
114
|
+
### Piece Component
|
|
115
|
+
|
|
116
|
+
Renders a CollageJS "piece" (micro-frontend) inside a Svelte application. The piece itself may be built using any
|
|
117
|
+
valid framework or library, as long as it adheres to the *CollageJS* `CorePiece` interface.
|
|
118
|
+
|
|
119
|
+
#### Props
|
|
120
|
+
|
|
121
|
+
Properties passed to the `Piece` component must include a special property created using the `piece()` helper
|
|
122
|
+
function. This property contains the `CorePiece` instance to render, along with optional container properties. One can
|
|
123
|
+
also pass additional properties that will be forwarded to the mounted piece.
|
|
124
|
+
|
|
125
|
+
If the mounted piece supports property updates, any changes to the additional properties will be propagated to the
|
|
126
|
+
piece reactively as per the rules of Svelte's reactivity system.
|
|
127
|
+
|
|
128
|
+
#### Example Usage
|
|
129
|
+
|
|
130
|
+
1. Import the `Piece` component and the `piece()` helper function from the library.
|
|
131
|
+
2. Import whatever you need to get a hold of your `CorePiece` instance. Normally, one imports a factory function that
|
|
132
|
+
creates the piece from a *bare module specifier* (an alias defined by your application's import map):
|
|
133
|
+
```typescript
|
|
134
|
+
import Piece, { piece } from '@collagejs/svelte';
|
|
135
|
+
import { myPieceFactory } from '@my/bare-module-specifier';
|
|
136
|
+
```
|
|
137
|
+
3. Create a `CorePiece` instance using your factory function. Pass whatever arguments the factory function requires.
|
|
138
|
+
4. Render the `Piece` component in your Svelte template, passing the `CorePiece` instance using the `piece()` helper
|
|
139
|
+
function. Also pass any additional properties that the piece supports:
|
|
140
|
+
|
|
141
|
+
```svelte
|
|
142
|
+
<Piece {...piece(myPieceFactory(), { class: 'my-piece-container' })} foo="bar" count={42} />
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The above sets the `my-piece-container` CSS class on the container element that wraps the piece, and also passes the
|
|
146
|
+
`foo` and `count` properties to the mounted piece. This example uses constant values in the properties, but you can
|
|
147
|
+
also pass stateful values that can update reactively, as if it were a regular Svelte component.
|
|
148
|
+
|
|
149
|
+
> ⚠️ **IMPORTANT**: Once a piece has unmounted, it cannot be remounted. You must create a new `CorePiece` instance
|
|
150
|
+
> and `<Piece>` instance. This is by design. The easiest is to have the call to the factory function inside the
|
|
151
|
+
> Svelte template, so that a new `CorePiece` instance is created each time a new `<Piece>` instance is created.
|
|
152
|
+
|
|
153
|
+
Online Documentation: Pending (https://collagejs.dev)
|
|
154
|
+
-->
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
declare const piecePropsSymbol: unique symbol;
|
|
2
|
+
/**
|
|
3
|
+
* Defines the special properties accepted by the `Piece` component. This type is to be used in conjunction with
|
|
4
|
+
* the `piece()` helper function to create the special property required by the `Piece` component.
|
|
5
|
+
*/
|
|
6
|
+
export type PieceProps<TProps extends Record<string, any> = Record<string, any>> = {
|
|
7
|
+
/**
|
|
8
|
+
* The special property that contains the `CorePiece` instance to render, along with optional container
|
|
9
|
+
* properties.
|
|
10
|
+
*/
|
|
11
|
+
[piecePropsSymbol]: {
|
|
12
|
+
/**
|
|
13
|
+
* The `CorePiece` instance to render.
|
|
14
|
+
*/
|
|
15
|
+
piece: CorePiece<TProps>;
|
|
16
|
+
/**
|
|
17
|
+
* Optional HTML attributes to set on the container element that wraps the piece.
|
|
18
|
+
*/
|
|
19
|
+
containerProps?: HTMLAttributes<HTMLDivElement>;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Helper function to create the special property required by the `Piece` component. The result of this function
|
|
24
|
+
* is to be spread into the props of the `Piece` component.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```svelte
|
|
28
|
+
* <Piece {...piece(myPiece, { onfocusin: focusInHandler })} foo="bar" count={42} />
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param piece The `CorePiece` instance to render.
|
|
32
|
+
* @param containerProps Optional HTML attributes to set on the container element that wraps the piece.
|
|
33
|
+
* @returns An object containing the special property to pass to the `Piece` component.
|
|
34
|
+
*/
|
|
35
|
+
export declare function piece<TProps extends Record<string, any> = Record<string, any>>(piece: CorePiece<TProps>, containerProps?: HTMLAttributes<HTMLDivElement>): {
|
|
36
|
+
[piecePropsSymbol]: {
|
|
37
|
+
piece: CorePiece<TProps>;
|
|
38
|
+
containerProps: HTMLAttributes<HTMLDivElement> | undefined;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
import { type CorePiece } from "@collagejs/core";
|
|
42
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
43
|
+
declare function $$render<TProps extends Record<string, any> = Record<string, any>>(): {
|
|
44
|
+
props: TProps & PieceProps<TProps>;
|
|
45
|
+
exports: {};
|
|
46
|
+
bindings: "";
|
|
47
|
+
slots: {};
|
|
48
|
+
events: {};
|
|
49
|
+
};
|
|
50
|
+
declare class __sveltets_Render<TProps extends Record<string, any> = Record<string, any>> {
|
|
51
|
+
props(): ReturnType<typeof $$render<TProps>>['props'];
|
|
52
|
+
events(): ReturnType<typeof $$render<TProps>>['events'];
|
|
53
|
+
slots(): ReturnType<typeof $$render<TProps>>['slots'];
|
|
54
|
+
bindings(): "";
|
|
55
|
+
exports(): {};
|
|
56
|
+
}
|
|
57
|
+
interface $$IsomorphicComponent {
|
|
58
|
+
new <TProps extends Record<string, any> = Record<string, any>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TProps>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TProps>['props']>, ReturnType<__sveltets_Render<TProps>['events']>, ReturnType<__sveltets_Render<TProps>['slots']>> & {
|
|
59
|
+
$$bindings?: ReturnType<__sveltets_Render<TProps>['bindings']>;
|
|
60
|
+
} & ReturnType<__sveltets_Render<TProps>['exports']>;
|
|
61
|
+
<TProps extends Record<string, any> = Record<string, any>>(internal: unknown, props: ReturnType<__sveltets_Render<TProps>['props']> & {}): ReturnType<__sveltets_Render<TProps>['exports']>;
|
|
62
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* ### Piece Component
|
|
66
|
+
*
|
|
67
|
+
* Renders a CollageJS "piece" (micro-frontend) inside a Svelte application. The piece itself may be built using any
|
|
68
|
+
* valid framework or library, as long as it adheres to the *CollageJS* `CorePiece` interface.
|
|
69
|
+
*
|
|
70
|
+
* #### Props
|
|
71
|
+
*
|
|
72
|
+
* Properties passed to the `Piece` component must include a special property created using the `piece()` helper
|
|
73
|
+
* function. This property contains the `CorePiece` instance to render, along with optional container properties. One can
|
|
74
|
+
* also pass additional properties that will be forwarded to the mounted piece.
|
|
75
|
+
*
|
|
76
|
+
* If the mounted piece supports property updates, any changes to the additional properties will be propagated to the
|
|
77
|
+
* piece reactively as per the rules of Svelte's reactivity system.
|
|
78
|
+
*
|
|
79
|
+
* #### Example Usage
|
|
80
|
+
*
|
|
81
|
+
* 1. Import the `Piece` component and the `piece()` helper function from the library.
|
|
82
|
+
* 2. Import whatever you need to get a hold of your `CorePiece` instance. Normally, one imports a factory function that
|
|
83
|
+
* creates the piece from a *bare module specifier* (an alias defined by your application's import map):
|
|
84
|
+
* ```typescript
|
|
85
|
+
* import Piece, { piece } from '@collagejs/svelte';
|
|
86
|
+
* import { myPieceFactory } from '@my/bare-module-specifier';
|
|
87
|
+
* ```
|
|
88
|
+
* 3. Create a `CorePiece` instance using your factory function. Pass whatever arguments the factory function requires.
|
|
89
|
+
* 4. Render the `Piece` component in your Svelte template, passing the `CorePiece` instance using the `piece()` helper
|
|
90
|
+
* function. Also pass any additional properties that the piece supports:
|
|
91
|
+
*
|
|
92
|
+
* ```svelte
|
|
93
|
+
* <Piece {...piece(myPieceFactory(), { class: 'my-piece-container' })} foo="bar" count={42} />
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* The above sets the `my-piece-container` CSS class on the container element that wraps the piece, and also passes the
|
|
97
|
+
* `foo` and `count` properties to the mounted piece. This example uses constant values in the properties, but you can
|
|
98
|
+
* also pass stateful values that can update reactively, as if it were a regular Svelte component.
|
|
99
|
+
*
|
|
100
|
+
* > ⚠️ **IMPORTANT**: Once a piece has unmounted, it cannot be remounted. You must create a new `CorePiece` instance
|
|
101
|
+
* > and `<Piece>` instance. This is by design. The easiest is to have the call to the factory function inside the
|
|
102
|
+
* > Svelte template, so that a new `CorePiece` instance is created each time a new `<Piece>` instance is created.
|
|
103
|
+
*
|
|
104
|
+
* Online Documentation: Pending (https://collagejs.dev)
|
|
105
|
+
*/
|
|
106
|
+
declare const Piece: $$IsomorphicComponent;
|
|
107
|
+
type Piece<TProps extends Record<string, any> = Record<string, any>> = InstanceType<typeof Piece<TProps>>;
|
|
108
|
+
export default Piece;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CollageContext } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Defines the context key used to store the parent-aware `mountPiece()` function.
|
|
4
|
+
*/
|
|
5
|
+
export declare const contextKey: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Obtains the *CollageJS* context, which is an object that contains the parent-aware `mountPiece()` function.
|
|
8
|
+
* @returns The stored *CollageJS* context.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getCollageContext(): CollageContext;
|
|
11
|
+
/**
|
|
12
|
+
* Sets the *CollageJS* context, which is an object that contains the parent-aware `mountPiece()` function.
|
|
13
|
+
* @param context The *CollageJS* context to store.
|
|
14
|
+
*/
|
|
15
|
+
export declare function setCollageContext(context: CollageContext): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getContext, setContext } from "svelte";
|
|
2
|
+
/**
|
|
3
|
+
* Defines the context key used to store the parent-aware `mountPiece()` function.
|
|
4
|
+
*/
|
|
5
|
+
export const contextKey = Symbol();
|
|
6
|
+
/**
|
|
7
|
+
* Obtains the *CollageJS* context, which is an object that contains the parent-aware `mountPiece()` function.
|
|
8
|
+
* @returns The stored *CollageJS* context.
|
|
9
|
+
*/
|
|
10
|
+
export function getCollageContext() {
|
|
11
|
+
return getContext(contextKey);
|
|
12
|
+
}
|
|
13
|
+
;
|
|
14
|
+
/**
|
|
15
|
+
* Sets the *CollageJS* context, which is an object that contains the parent-aware `mountPiece()` function.
|
|
16
|
+
* @param context The *CollageJS* context to store.
|
|
17
|
+
*/
|
|
18
|
+
export function setCollageContext(context) {
|
|
19
|
+
setContext(contextKey, context);
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ComponentOperationOptions } from "../types.js";
|
|
2
|
+
import { type MountProps } from "@collagejs/core";
|
|
3
|
+
import { mount, unmount, type Component } from "svelte";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a `buildPiece` function for Svelte v5 components.
|
|
6
|
+
* @param mountFn Svelte's mount() function (or a substitute).
|
|
7
|
+
* @param unmountFn Svelte's unmount() function (or a substitute).
|
|
8
|
+
* @returns A `buildPiece` function that uses the given mounting and unmounting functions.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildPieceFactory(mountFn?: typeof mount, unmountFn?: typeof unmount): <TProps extends Record<string, any> = Record<string, any>>(component: Component<TProps>, options?: ComponentOperationOptions<TProps>) => {
|
|
11
|
+
mount: (target: HTMLElement, props?: MountProps<TProps> | undefined) => Promise<() => Promise<void>>;
|
|
12
|
+
update: (newProps: TProps) => Promise<void>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { contextKey } from "../collageContext.js";
|
|
2
|
+
import { mountPieceKey } from "@collagejs/core";
|
|
3
|
+
import { mount, unmount } from "svelte";
|
|
4
|
+
/**
|
|
5
|
+
* Class used to track instances.
|
|
6
|
+
*/
|
|
7
|
+
class SveltePiece {
|
|
8
|
+
props = $state({});
|
|
9
|
+
target;
|
|
10
|
+
instance;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a `buildPiece` function for Svelte v5 components.
|
|
14
|
+
* @param mountFn Svelte's mount() function (or a substitute).
|
|
15
|
+
* @param unmountFn Svelte's unmount() function (or a substitute).
|
|
16
|
+
* @returns A `buildPiece` function that uses the given mounting and unmounting functions.
|
|
17
|
+
*/
|
|
18
|
+
export function buildPieceFactory(mountFn = mount, unmountFn = unmount) {
|
|
19
|
+
return function (component, options) {
|
|
20
|
+
if (!component) {
|
|
21
|
+
throw new Error('No component was given to the function.');
|
|
22
|
+
}
|
|
23
|
+
if (options?.mount?.target) {
|
|
24
|
+
console.warn("Specifying the 'target' mount option has no effect.");
|
|
25
|
+
}
|
|
26
|
+
const thisValue = new SveltePiece();
|
|
27
|
+
async function mountComponent(target, props) {
|
|
28
|
+
this.target = target;
|
|
29
|
+
await options?.preMount?.(this.target);
|
|
30
|
+
// Don't lose any potential incoming context.
|
|
31
|
+
let context = options?.mount?.context ?? new Map();
|
|
32
|
+
context.set(contextKey, {
|
|
33
|
+
mountPiece: props?.[mountPieceKey]
|
|
34
|
+
});
|
|
35
|
+
delete props?.[mountPieceKey];
|
|
36
|
+
const mergedProps = {
|
|
37
|
+
...options?.mount?.props,
|
|
38
|
+
...props
|
|
39
|
+
};
|
|
40
|
+
for (let key in mergedProps) {
|
|
41
|
+
this.props[key] = mergedProps[key];
|
|
42
|
+
}
|
|
43
|
+
this.instance = mountFn(component, {
|
|
44
|
+
...options?.mount,
|
|
45
|
+
context,
|
|
46
|
+
target: this.target,
|
|
47
|
+
props: this.props
|
|
48
|
+
});
|
|
49
|
+
return async () => {
|
|
50
|
+
if (!this.instance) {
|
|
51
|
+
throw new Error('Cannot unmount: There is no component to unmount.');
|
|
52
|
+
}
|
|
53
|
+
await unmountFn(this.instance, options?.unmount);
|
|
54
|
+
await options?.postUnmount?.(this.target);
|
|
55
|
+
this.instance = undefined;
|
|
56
|
+
this.target = undefined;
|
|
57
|
+
this.props = {};
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function updateComponent(newProps) {
|
|
61
|
+
if (!this.instance) {
|
|
62
|
+
return Promise.reject(new Error('Cannot update: No component has been mounted.'));
|
|
63
|
+
}
|
|
64
|
+
for (let key in newProps) {
|
|
65
|
+
this.props[key] = newProps[key];
|
|
66
|
+
}
|
|
67
|
+
// TODO: Perhaps we need await tick() here?
|
|
68
|
+
return Promise.resolve();
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
mount: mountComponent.bind(thisValue),
|
|
72
|
+
update: updateComponent.bind(thisValue)
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { default as Piece } from './Piece/Piece.svelte';
|
|
2
|
+
export * from './Piece/Piece.svelte';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a `CorePiece`-compliant object from a Svelte component.
|
|
5
|
+
* @param component The Svelte component to wrap.
|
|
6
|
+
* @param options Optional options object for additional features and configuration of the mount/unmount process.
|
|
7
|
+
* @returns A `CorePiece`-compliant object that wraps the given Svelte component.
|
|
8
|
+
*/
|
|
9
|
+
export declare const buildPiece: <TProps extends Record<string, any> = Record<string, any>>(component: import("svelte").Component<TProps>, options?: import("./types.ts").ComponentOperationOptions<TProps>) => {
|
|
10
|
+
mount: (target: HTMLElement, props?: import("@collagejs/core").MountProps<TProps> | undefined) => Promise<() => Promise<void>>;
|
|
11
|
+
update: (newProps: TProps) => Promise<void>;
|
|
12
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { buildPieceFactory } from "./collagejs/collage.svelte.js";
|
|
2
|
+
export { default as Piece } from './Piece/Piece.svelte';
|
|
3
|
+
export * from './Piece/Piece.svelte';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a `CorePiece`-compliant object from a Svelte component.
|
|
6
|
+
* @param component The Svelte component to wrap.
|
|
7
|
+
* @param options Optional options object for additional features and configuration of the mount/unmount process.
|
|
8
|
+
* @returns A `CorePiece`-compliant object that wraps the given Svelte component.
|
|
9
|
+
*/
|
|
10
|
+
export const buildPiece = buildPieceFactory();
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { MountOptions, unmount } from "svelte";
|
|
2
|
+
import type { MountPiece } from "@collagejs/core";
|
|
3
|
+
/**
|
|
4
|
+
* Options for Svelte's `mount()` function.
|
|
5
|
+
*/
|
|
6
|
+
export type SvelteMountOptions<TProps extends Record<string, any> = Record<string, any>> = Omit<MountOptions<TProps>, 'target'>;
|
|
7
|
+
/**
|
|
8
|
+
* Options given to the lifecycle-creation function.
|
|
9
|
+
*/
|
|
10
|
+
export type ComponentOperationOptions<TProps extends Record<string, any> = Record<string, any>> = {
|
|
11
|
+
/**
|
|
12
|
+
* Optional function to be run immediately before Svelte mounts the component.
|
|
13
|
+
*
|
|
14
|
+
* An error thrown from this function will make the mount promise to reject.
|
|
15
|
+
* @param target HTML element where the Svelte component will be mounted in.
|
|
16
|
+
*/
|
|
17
|
+
preMount?: (target: HTMLElement) => Promise<void> | void;
|
|
18
|
+
/**
|
|
19
|
+
* Optional function to be run immediately after Svelte unmounts the component.
|
|
20
|
+
*
|
|
21
|
+
* An error thrown from this function will make the unmount promise to reject.
|
|
22
|
+
* @param target HTML element where the Svelte component was mounted in.
|
|
23
|
+
*/
|
|
24
|
+
postUnmount?: (target: HTMLElement) => Promise<void> | void;
|
|
25
|
+
/**
|
|
26
|
+
* Optional options for Svelte's `mount()` function. Refer to Svelte's `mount()` function documentation for
|
|
27
|
+
* information about each option.
|
|
28
|
+
*/
|
|
29
|
+
mount?: SvelteMountOptions<TProps>;
|
|
30
|
+
/**
|
|
31
|
+
* Optional options for Svelte's `unmount()` function. Refer to Svelte's `unmount()` function documentation for
|
|
32
|
+
* information about each option.
|
|
33
|
+
*/
|
|
34
|
+
unmount?: Parameters<typeof unmount>[1];
|
|
35
|
+
};
|
|
36
|
+
export type CollageContext = {
|
|
37
|
+
mountPiece: MountPiece;
|
|
38
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@collagejs/svelte",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Svelte v5 integration for the CollageJS micro-frontend library",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "José Pablo Ramírez Vargas",
|
|
7
|
+
"email": "webJose@gmail.com",
|
|
8
|
+
"url": "https://github.com/webJose"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/collagejs/svelte.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/collagejs/svelte/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://collagejs.dev",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "vite dev",
|
|
20
|
+
"build": "vite build && npm run prepack",
|
|
21
|
+
"preview": "vite preview",
|
|
22
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
23
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
24
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
25
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
26
|
+
"test:unit": "vitest",
|
|
27
|
+
"test": "npm run test:unit -- --run",
|
|
28
|
+
"test:e2e": "playwright test"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"!dist/testing",
|
|
33
|
+
"!dist/**/*.test.*",
|
|
34
|
+
"!dist/**/*.spec.*"
|
|
35
|
+
],
|
|
36
|
+
"sideEffects": [
|
|
37
|
+
"**/*.css"
|
|
38
|
+
],
|
|
39
|
+
"svelte": "./dist/index.js",
|
|
40
|
+
"types": "./dist/index.d.ts",
|
|
41
|
+
"type": "module",
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"svelte": "./dist/index.js"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"svelte": "^5.0.0",
|
|
50
|
+
"@collagejs/core": "^0.1.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@playwright/test": "^1.57.0",
|
|
54
|
+
"@sveltejs/adapter-auto": "^7.0.0",
|
|
55
|
+
"@sveltejs/kit": "^2.49.1",
|
|
56
|
+
"@sveltejs/package": "^2.5.7",
|
|
57
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
58
|
+
"@vitest/browser-playwright": "^4.0.15",
|
|
59
|
+
"playwright": "^1.57.0",
|
|
60
|
+
"publint": "^0.3.15",
|
|
61
|
+
"svelte": "^5.45.6",
|
|
62
|
+
"svelte-check": "^4.3.4",
|
|
63
|
+
"typescript": "^5.9.3",
|
|
64
|
+
"vite": "^7.2.6",
|
|
65
|
+
"vitest": "^4.0.15",
|
|
66
|
+
"vitest-browser-svelte": "^2.0.1"
|
|
67
|
+
},
|
|
68
|
+
"keywords": [
|
|
69
|
+
"svelte",
|
|
70
|
+
"collage",
|
|
71
|
+
"collage-js",
|
|
72
|
+
"collagejs",
|
|
73
|
+
"micro-frontend",
|
|
74
|
+
"mfe",
|
|
75
|
+
"single-spa"
|
|
76
|
+
]
|
|
77
|
+
}
|