@collagejs/core 0.2.0 → 0.4.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Micro library for framework-agnostic micro-frontends
4
4
 
5
- **🚧🚧 YOU'RE EARLY. WORK IN PROGRESS... ETA: Early February, 2026 🚧🚧**
5
+ **🚧🚧 I'M LATE. WORK IN PROGRESS... ETA: JULY, 2026 🚧🚧**
6
6
 
7
7
  **If you're interested, star ⭐ the repository to get updates on the progress in your GH homepage.**
8
8
 
@@ -10,7 +10,11 @@
10
10
 
11
11
  [Full Documentation](https://collagejs.dev)
12
12
 
13
- *CollageJS* is a very, very small library that enables the composition of a web user interface with micro-frontends created with any technology (Svelte, React, Vue, SolidJS, HTMX, etc.). It is heavily inspired by the *parcel* concept in the excellent `single-spa` routing library.
13
+ > 📰 **SAD NEWS**
14
+ >
15
+ > `single-spa` creator *Joel/Jolyn Denning* [has passed away in late 2025](https://github.com/single-spa/single-spa/issues/1361#issuecomment-3991093643).
16
+
17
+ *CollageJS* is a very, very small library that enables the composition of a web user interface with micro-frontends created with any technology (Svelte, React, Vue, SolidJS, HTMX, Lit, Ripple-TS, etc.). It is heavily inspired by the *parcel* concept in the excellent `single-spa` routing library.
14
18
 
15
19
  ## How It Works
16
20
 
@@ -20,7 +24,7 @@
20
24
  type UnmountFn = () => Promise<void>;
21
25
 
22
26
  interface CorePiece<TProps> {
23
- mount: (target: HTMLElement, props?: TProps) => Promise<UnmountFn>;
27
+ mount: (target: HTMLElement | ShadowRoot, props?: TProps) => Promise<UnmountFn>;
24
28
  update?: (props: TProps) => Promise<void>;
25
29
  };
26
30
  ```
@@ -42,7 +46,7 @@ This is a simple example that shows a tiny, yet complete micro-frontend made wit
42
46
  ```typescript
43
47
  export function buildTestPiece<TProps extends Record<string, any> = Record<string, any>>(
44
48
  callbacks?: {
45
- mount: (target: HTMLElement, props?: MountProps<TProps>) => void | (() => void);
49
+ mount: (target: AcceptableTarget, props?: MountProps<TProps>) => void | (() => void);
46
50
  unmount: () => void;
47
51
  update: (props: TProps) => void;
48
52
  }
@@ -50,7 +54,7 @@ export function buildTestPiece<TProps extends Record<string, any> = Record<strin
50
54
  let pre: HTMLElement;
51
55
  return {
52
56
  // Here's mount():
53
- async mount(target: HTMLElement, props?: MountProps<TProps>) {
57
+ async mount(target: AcceptableTarget, props?: MountProps<TProps>) {
54
58
  const delayMountCb = callbacks?.mount?.(target, props);
55
59
  pre = document.createElement('pre');
56
60
  pre.setAttribute('data-testid', pieceTestId);
@@ -138,7 +142,7 @@ Then the micro-frontends: The concept doesn't exist. At this point (after crea
138
142
 
139
143
  While `single-spa` asks you to shape your module exports in a particular way (the lifecycle functions), *CollageJS* imposes no such restriction. It is just not necessary. Just make sure you can get an object of type `CorePiece` to the `<Piece>` component of your preferred framework. Then use your framework's marvels to make the `<Piece>` component appear or disappear.
140
144
 
141
- Yes, you'll still be working with import maps. They are super handy. We provide an enhanced (and simplified at the same time) version of `import-map-overrides` named `@collagejs/imo`. It only supports the `overridable-importmap` type (and therefore only native import maps for native ES modules), but carries support for our `@collagejs/aim` plug-in that let's you statically import from micro-frontends. **That's right! We are free from dynamic `import()` calls!** We can statically import from micro-frontends. Furthermore, it has a more modern user interface:
145
+ Yes, you'll still be working with import maps. They are super handy. We provide an enhanced (and simplified at the same time) version of `import-map-overrides` named `@collagejs/imo`. It only supports the `overridable-importmap` type (and therefore only native import maps for native ES modules), but carries support for our `@collagejs/vite-aim` plug-in that let's you statically import from micro-frontends. **That's right! We are free from dynamic `import()` calls!** We can statically import from micro-frontends. Furthermore, it has a more modern user interface:
142
146
 
143
147
  ![Main screen of @collagejs/imo](./_docs/collagejs-imo.png)
144
148
 
@@ -158,12 +162,12 @@ Gone. There's no equivalent in *CollageJS*, as experience with `single-spa` has
158
162
  | - | - | - | - |
159
163
  | `@collagejs/core` | ✔️ | (This repo) | Core functionality. Provides the general mounting and unmounting logic. |
160
164
  | `@collagejs/vite-css` | ✔️ | [Repo](https://github.com/collagejs/vite) | Vite plug-in that offers a CSS-mounting algorithm that is fully compatible with Vite's CSS bundling, including split CSS. It also features FOUC prevention. |
161
- | `@collagejs/vite-im` | 🚧 | [Repo](https://github.com/collagejs/vite) | **Coming soon**. Vite plug-in that injects an import map and optionally the `import-map-overrides` package to define bare module identifiers for easy micro-frontend loading and debugging. |
162
- | `@collagejs/vite-aim` | 🚧 | [Repo](https://github.com/collagejs/vite) | **Coming soon**. Vite-plugin that gives the Vite development server the ability to accept import maps from the client, which are used to resolve modules in the Vite pipeline, enabling static imports from micro-frontend bare module identifiers. |
163
- | `@collagejs/imo` | 🚧 | [Repo](https://github.com/collagejs/imo) | **Coming soon**. Our version of `import-map-overrides` that does the usual overriding of import map entries, plus it transmits the final import map to Vite development servers found in it. |
165
+ | `@collagejs/vite-im` | ✔️ | [Repo](https://github.com/collagejs/vite) | Vite plug-in that injects an import map and optionally the `import-map-overrides` package to define bare module identifiers for easy micro-frontend loading and debugging. |
166
+ | `@collagejs/vite-aim` | ✔️ | [Repo](https://github.com/collagejs/vite) | Vite-plugin that gives the Vite development server the ability to accept import maps from the client, which are used to resolve modules in the Vite pipeline, enabling static imports from micro-frontend bare module identifiers. |
167
+ | `@collagejs/imo` | ✔️ | [Repo](https://github.com/collagejs/imo) | Our version of `import-map-overrides` that does the usual overriding of import map entries, plus it transmits the final import map to Vite development servers found in it. |
164
168
  | `@collagejs/svelte` | ✔️ | [Repo](https://github.com/collagejs/svelte) | Svelte component library that can be used to create `CorePiece`-compliant objects and to mount `CorePiece` objects (of any technology) by providing the `<Piece>` component. |
165
- | `@collagejs/react` | | [Repo](https://github.com/collagejs/react) | **Next priority**. React component library that can be used to create `CorePiece`-compliant objects and to mount `CorePiece` objects (of any technology) by providing the `<Piece>` component. |
166
- | `@collagejs/solidjs` | ❌ | [Repo](https://github.com/collagejs/vite) | SolidJS component library that can be used to create `CorePiece`-compliant objects and to mount `CorePiece` objects (of any technology) by providing the `<Piece>` component. |
169
+ | `@collagejs/react` | 🚧 | [Repo](https://github.com/collagejs/react) | **Coming soon**. React component library that can be used to create `CorePiece`-compliant objects and to mount `CorePiece` objects (of any technology) by providing the `<Piece>` component. |
170
+ | `@collagejs/solidjs` | ❌ | [Repo](https://github.com/collagejs/solidjs) | SolidJS component library that can be used to create `CorePiece`-compliant objects and to mount `CorePiece` objects (of any technology) by providing the `<Piece>` component. |
167
171
  | `@collagejs/vue` | ❌ | [Repo](https://github.com/collagejs/vue) | VueJS component library that can be used to create `CorePiece`-compliant objects and to mount `CorePiece` objects (of any technology) by providing the `<Piece>` component. |
168
172
  | `@collagejs/angular` | ❌ | | **External help needed.** We don't have expertise in Angular, nor do we want to acquire it. If you're an Angular developer, please consider contributing. |
169
173
 
@@ -1,10 +1,10 @@
1
- import type { CorePiece, MountPiece } from "./types.js";
1
+ import type { CorePiece, MountPiece, AcceptableTarget } from "./types.js";
2
2
  export declare const mountKey: unique symbol;
3
3
  export declare class MountedPiece<TProps extends Record<string, any> = Record<string, any>> {
4
4
  #private;
5
5
  get mountPiece(): MountPiece<TProps>;
6
6
  constructor(piece: CorePiece<TProps>, mountPiece: MountPiece<TProps>, parent?: MountedPiece);
7
- [mountKey](target: HTMLElement, props?: TProps): Promise<void>;
7
+ [mountKey](target: AcceptableTarget, props?: TProps): Promise<void>;
8
8
  unmount(): Promise<void>;
9
9
  update(props: TProps): Promise<void>;
10
10
  }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Ensures that the global CollageJs object exists.
3
+ */
4
+ export declare function ensureGlobalCollageJs(): void;
package/dist/global.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Ensures that the global CollageJs object exists.
3
+ */
4
+ export function ensureGlobalCollageJs() {
5
+ if (!globalThis.CollageJs) {
6
+ globalThis.CollageJs = {};
7
+ }
8
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export type * from './types.js';
2
2
  export { mountPiece } from './mountPiece.js';
3
3
  export { mountPieceKey } from './common.js';
4
+ export { ensureGlobalCollageJs } from './global.js';
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { mountPiece } from './mountPiece.js';
2
2
  export { mountPieceKey } from './common.js';
3
+ export { ensureGlobalCollageJs } from './global.js';
@@ -1,5 +1,5 @@
1
1
  import { MountedPiece } from "./MountedPiece.js";
2
- import type { CorePiece, MountPiece } from "./types.js";
2
+ import type { AcceptableTarget, CorePiece, MountPiece } from "./types.js";
3
3
  /**
4
4
  * Constructor type for MountedPiece classes.
5
5
  *
@@ -8,11 +8,11 @@ import type { CorePiece, MountPiece } from "./types.js";
8
8
  export interface MountedPieceConstructor {
9
9
  new <TProps extends Record<string, any> = Record<string, any>>(piece: CorePiece<TProps>, mountPiece: MountPiece<any>, parent?: MountedPiece<any>): MountedPiece<TProps>;
10
10
  }
11
- export declare function mountPieceCore<TProps extends Record<string, any> = Record<string, any>>(this: MountedPiece | undefined, piece: CorePiece<TProps> | Promise<CorePiece<TProps>>, target: HTMLElement, props?: TProps, MountedPieceClass?: MountedPieceConstructor): Promise<MountedPiece<TProps>>;
11
+ export declare function mountPieceCore<TProps extends Record<string, any> = Record<string, any>>(this: MountedPiece | undefined, piece: CorePiece<TProps> | Promise<CorePiece<TProps>>, target: AcceptableTarget, props?: TProps, MountedPieceClass?: MountedPieceConstructor): Promise<MountedPiece<TProps>>;
12
12
  /**
13
13
  * Mounts the CollageJS piece as a child of the target element.
14
14
  * @param piece The CollageJS piece to mount.
15
- * @param target The target element to mount the piece to.
15
+ * @param target The target HTML element or shadow root where to mount the piece.
16
16
  * @param props The properties to pass to the piece.
17
17
  */
18
- export declare function mountPiece<TProps extends Record<string, any> = Record<string, any>>(piece: CorePiece<TProps>, target: HTMLElement, props?: TProps): Promise<MountedPiece<TProps>>;
18
+ export declare function mountPiece<TProps extends Record<string, any> = Record<string, any>>(piece: CorePiece<TProps>, target: AcceptableTarget, props?: TProps): Promise<MountedPiece<TProps>>;
@@ -10,7 +10,7 @@ export async function mountPieceCore(piece, target, props, MountedPieceClass = M
10
10
  /**
11
11
  * Mounts the CollageJS piece as a child of the target element.
12
12
  * @param piece The CollageJS piece to mount.
13
- * @param target The target element to mount the piece to.
13
+ * @param target The target HTML element or shadow root where to mount the piece.
14
14
  * @param props The properties to pass to the piece.
15
15
  */
16
16
  export function mountPiece(piece, target, props) {
package/dist/types.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Defines the type for acceptable targets for mounting *CollageJS* pieces.
3
+ */
4
+ export type AcceptableTarget = HTMLElement | ShadowRoot;
1
5
  /**
2
6
  * Properties passed to `mount()` functions of `CorePiece` objects. It extends the piece's supported objects with a
3
7
  * property of type `symbol` that carries the piece parent's `mountPiece()` function.
@@ -11,11 +15,11 @@ export type MountProps<TProps extends Record<string, any> = Record<string, any>>
11
15
  export type UnmountFn = () => Promise<void>;
12
16
  /**
13
17
  * Type that defines the signature of the functions accepted in `CorePiece.mount`.
14
- * @param target The HTML target where the piece will be mounted as a child.
18
+ * @param target The HTML or shadow root target where the piece will be mounted as a child.
15
19
  * @param props The piece's initial property values.
16
20
  * @returns A promise to the cleanup function that unmounts the piece.
17
21
  */
18
- export type MountFn<TProps extends Record<string, any> = Record<string, any>> = (target: HTMLElement, props?: MountProps<TProps>) => Promise<UnmountFn>;
22
+ export type MountFn<TProps extends Record<string, any> = Record<string, any>> = (target: AcceptableTarget, props?: MountProps<TProps>) => Promise<UnmountFn>;
19
23
  /**
20
24
  * Type that defines the signature of the functions accepted in `CorePiece.update`.
21
25
  * @param props The new property values for the mounted piece.
@@ -73,7 +77,18 @@ export interface MountedPiece<TProps extends Record<string, any> = Record<string
73
77
  * generates a version of the global function that works identically, except that it tracks the `CollageJS` pieces
74
78
  * mounted with it so these are unmounted automatically as soon as the parent is unmounted.
75
79
  * @param piece `CorePiece` object to mount in the provided target, or a promise that resolves said object.
76
- * @param target HTML element where to mount
80
+ * @param target HTML element or shadow root where to mount.
77
81
  * @param props Optional properties for the `CorePiece` object.
78
82
  */
79
- export type MountPiece<TProps extends Record<string, any> = Record<string, any>> = (piece: CorePiece<TProps> | Promise<CorePiece<TProps>>, target: HTMLElement, props?: TProps) => Promise<MountedPiece<TProps>>;
83
+ export type MountPiece<TProps extends Record<string, any> = Record<string, any>> = (piece: CorePiece<TProps> | Promise<CorePiece<TProps>>, target: AcceptableTarget, props?: TProps) => Promise<MountedPiece<TProps>>;
84
+ declare global {
85
+ /**
86
+ * Defines the capabilities in the global `CollageJs` object.
87
+ */
88
+ interface CollageJs {
89
+ }
90
+ /**
91
+ * Global object that provides functionality outside bundling.
92
+ */
93
+ var CollageJs: CollageJs;
94
+ }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@collagejs/core",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Core functionality for CollageJS.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "scripts": {
8
- "test": "npm run check && npm run test:unit && npm run test:types",
9
- "test:unit": "ts-mocha -n loader=ts-node/esm -p ./tsconfig.json --require ./tests/setup.ts ./tests/ut/**/*.test.ts",
10
- "test:watch": "ts-mocha -n loader=ts-node/esm -p ./tsconfig.json --require ./tests/setup.ts ./tests/ut/**/*.test.ts --watch",
8
+ "test": "npm run test:unit && npm run test:types",
9
+ "test:unit": "vitest run",
10
+ "test:watch": "vitest",
11
11
  "test:types": "tstyche ./tests/typetests",
12
12
  "build": "tsc && pwsh -File ./post-build.ps1 && publint",
13
13
  "check": "tsc --noEmit"
@@ -65,20 +65,16 @@
65
65
  "files": [
66
66
  "dist"
67
67
  ],
68
+ "sideEffects": false,
68
69
  "devDependencies": {
69
- "@types/chai": "^5.2.2",
70
- "@types/jsdom": "^27.0.0",
71
- "@types/mocha": "^10.0.10",
72
- "@types/node": "^25.0.1",
70
+ "@types/jsdom": "^28.0.3",
71
+ "@types/node": "^26.0.0",
73
72
  "@types/sinon": "^21.0.0",
74
- "chai": "^6.0.1",
75
- "jsdom": "^27.3.0",
76
- "mocha": "^11.7.2",
73
+ "jsdom": "^29.1.1",
77
74
  "publint": "^0.3.11",
78
- "sinon": "^21.0.0",
79
- "ts-mocha": "^11.1.0",
80
- "ts-node": "^10.9.2",
81
- "tstyche": "^5.0.2",
82
- "typescript": "^5.8.2"
75
+ "sinon": "^22.0.0",
76
+ "tstyche": "^7.2.1",
77
+ "typescript": "^6.0.3",
78
+ "vitest": "^4.1.9"
83
79
  }
84
80
  }