create-outsystems-astro 0.5.0 → 0.7.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.
Files changed (61) hide show
  1. package/README.md +50 -11
  2. package/bin/cli.js +71 -5
  3. package/package.json +1 -1
  4. package/template/.prettierignore +2 -0
  5. package/template/.prettierrc +4 -0
  6. package/template/AGENTS.md +145 -22
  7. package/template/astro.config.mjs +15 -2
  8. package/template/bun.lock +529 -716
  9. package/template/deno.json +14 -7
  10. package/template/deno.lock +1100 -688
  11. package/template/eslint.config.mjs +43 -0
  12. package/template/output.ts +14 -2
  13. package/template/package-lock.json +3404 -3080
  14. package/template/package.json +59 -85
  15. package/template/patches/{@angular+build+21.2.0.patch → @angular+build+21.2.1.patch} +1 -10
  16. package/template/patches-deno/playwright+1.58.2.patch +26 -0
  17. package/template/playwright.config.ts +1 -1
  18. package/template/pnpm-lock.yaml +2041 -1584
  19. package/template/pnpm-workspace.yaml +6 -0
  20. package/template/src/framework/angular/{Counter.component.ts → Demo.component.ts} +12 -5
  21. package/template/src/framework/angular/Store.component.ts +24 -0
  22. package/template/src/framework/preact/Demo.tsx +86 -0
  23. package/template/src/framework/preact/Store.tsx +31 -0
  24. package/template/src/framework/react/{Counter.tsx → Demo.tsx} +23 -17
  25. package/template/src/framework/react/Store.tsx +31 -0
  26. package/template/src/framework/svelte/Demo.svelte +74 -0
  27. package/template/src/framework/svelte/Store.svelte +22 -0
  28. package/template/src/framework/vue/{Counter.vue → Demo.vue} +7 -9
  29. package/template/src/framework/vue/Store.vue +28 -0
  30. package/template/src/images/angular.png +0 -0
  31. package/template/src/images/preact.png +0 -0
  32. package/template/src/images/react.png +0 -0
  33. package/template/src/images/svelte.png +0 -0
  34. package/template/src/images/vue.png +0 -0
  35. package/template/src/pages/angular/angular-demo.astro +42 -0
  36. package/template/src/pages/multi/store.astro +22 -0
  37. package/template/src/pages/preact/preact-demo.astro +66 -0
  38. package/template/src/pages/react/react-demo.astro +66 -0
  39. package/template/src/pages/svelte/svelte-demo.astro +63 -0
  40. package/template/src/pages/vue/vue-demo.astro +61 -0
  41. package/template/src/stores/framework.ts +10 -0
  42. package/template/src/styles/index.css +4 -0
  43. package/template/svelte.config.js +5 -0
  44. package/template/test/e2e/angular/angular-counter.spec.ts +7 -1
  45. package/template/test/e2e/preact/preact-counter.spec.ts +42 -0
  46. package/template/test/e2e/react/react-counter.spec.ts +2 -2
  47. package/template/test/e2e/svelte/svelte-counter.spec.ts +42 -0
  48. package/template/test/e2e/vue/vue-counter.spec.ts +2 -2
  49. package/template/test/integration/angular/{Counter.component.spec.ts → Demo.component.spec.ts} +6 -6
  50. package/template/test/integration/preact/Demo.test.tsx +84 -0
  51. package/template/test/integration/react/{Counter.test.tsx → Demo.test.tsx} +10 -9
  52. package/template/test/integration/svelte/Demo.test.ts +81 -0
  53. package/template/test/integration/svelte/Demo.wrapper.svelte +27 -0
  54. package/template/test/integration/vue/{Counter.test.ts → Demo.test.ts} +9 -9
  55. package/template/tsconfig.json +0 -1
  56. package/template/vitest.config.ts +29 -2
  57. package/template/yarn.lock +2311 -2251
  58. package/template/src/pages/angular/angular-counter.astro +0 -31
  59. package/template/src/pages/react/react-counter.astro +0 -58
  60. package/template/src/pages/vue/vue-counter.astro +0 -62
  61. /package/template/patches/{@analogjs+astro-angular+2.3.0.patch → @analogjs+astro-angular+2.3.1.patch} +0 -0
package/README.md CHANGED
@@ -13,7 +13,9 @@ Generates [Astro Islands](https://docs.astro.build/en/concepts/islands/) for use
13
13
 
14
14
  ## Current supported frameworks
15
15
  - [Angular](https://analogjs.org/docs/packages/astro-angular/overview)
16
+ - [Preact](https://docs.astro.build/en/guides/integrations-guide/preact/)
16
17
  - [React](https://docs.astro.build/en/guides/integrations-guide/react/)
18
+ - [Svelte](https://docs.astro.build/en/guides/integrations-guide/svelte/)
17
19
  - [Vue](https://docs.astro.build/en/guides/integrations-guide/vue/)
18
20
 
19
21
  ## Getting started
@@ -55,29 +57,66 @@ This will create the generated files as well as an example component.
55
57
  /
56
58
  ├── public/
57
59
  ├── src/
58
- │ └── components/
59
- │ └── Counter.tsx
60
+ │ └── framework/
61
+ │ └── [NAME]/
62
+ │ └── components/
63
+ │ └── Counter.tsx
64
+ │ └── lib/
65
+ │ └── library.ts
60
66
  │ └── images/
61
67
  │ └── image.png
62
68
  │ └── pages/
63
- │ └── counter.astro
69
+ │ └── [NAME]/
70
+ │ └── page.astro
64
71
  │ └── styles/
65
72
  │ └── index.css
73
+ │ └── stores/
74
+ │ └── store.ts
75
+ ├── test/
76
+ │ └── e2e
77
+ │ └── [NAME]/
78
+ │ └── counter.spec.ts
79
+ │ └── integration
80
+ │ └── [NAME]/
81
+ │ └── counter.test.tsx
82
+ │ └── conter.test.ts
83
+ │ └── unit
84
+ └── counter.test.ts
66
85
  └── package.json
67
86
  ```
68
87
 
69
- ### Pages
70
- Each page inside of the pages file should represent an Island that will be imported into OutSystems.
88
+ ### Src
71
89
 
72
- ### Components
73
- The location of the component code.
90
+ #### Framework Components
91
+ The location of the component code. Each framework has its own separate folder.
74
92
 
75
- ### Images
93
+ #### Lib
94
+ Cane be use for shared/library logic that is not part of the visual presentation of the component.
95
+
96
+ #### Images
76
97
  Any image assets.
77
98
 
78
- ### Styles
99
+ #### Pages
100
+ Each page inside of the pages file should represent an Island that will be imported into OutSystems. This is for setup/development and the actual page will not be used for the final output. Pages may be split by framework if using multiple frameworks.
101
+
102
+ #### Styles
79
103
  Stylesheets that may apply to the component.
80
104
 
105
+ #### Stores
106
+ Nano Stores for use in components.
107
+
108
+ ### Test
109
+
110
+ #### E2E
111
+ End-to-end tests using Playwright.
112
+
113
+ #### Integration
114
+ Integration tests that test the whole component structure. Written using Testing Library specific providers.
115
+
116
+ #### Unit
117
+ Unit tests for functions or shared code/libraries.
118
+
119
+
81
120
  ## 🧞 Commands
82
121
 
83
122
  All commands are run from the root of the project, from a terminal:
@@ -138,7 +177,7 @@ All commands are run from the root of the project, from a terminal:
138
177
 
139
178
  | Command | Action |
140
179
  | :------------------------ | :----------------------------------------------- |
141
- | `deno install && deno run postinstall` | Installs dependencies |
180
+ | `deno install && deno run postinstall:deno` | Installs dependencies |
142
181
  | `deno run dev` | Starts local dev server at `localhost:4321` |
143
182
  | `deno run build` | Build distribution to `./dist/` |
144
183
  | `deno run output:deno` | Build OutSystems production site to `./output/` |
@@ -148,7 +187,7 @@ All commands are run from the root of the project, from a terminal:
148
187
  | `deno run audit:deno` | Run audit of modules |
149
188
 
150
189
  ## Getting Started
151
- Delete the demo application under the ```src``` folder and being to build your own application.
190
+ Delete the demo application under the ```src``` folder and being to build your own application. It is recommended to keep the folder structure. The frameworks/[NAME]/components should be kept for asset building.
152
191
 
153
192
  ## Converting to OutSystems
154
193
 
package/bin/cli.js CHANGED
@@ -16,14 +16,16 @@ const __dirname = path.dirname(__filename);
16
16
 
17
17
  const FRAMEWORKS = [
18
18
  { title: "Angular", value: "angular" },
19
+ { title: "Preact", value: "preact" },
19
20
  { title: "React", value: "react" },
21
+ { title: "Svelte", value: "svelte" },
20
22
  { title: "Vue", value: "vue" }
21
23
  ];
22
24
 
23
25
  const LOCKFILES = {
24
26
  npm: ["package-lock.json"],
25
27
  yarn: ["yarn.lock"],
26
- pnpm: ["pnpm-lock.yaml"],
28
+ pnpm: ["pnpm-lock.yaml", "pnpm-workspace.yaml"],
27
29
  bun: ["bun.lock"],
28
30
  deno: ["deno.lock", "deno.json"]
29
31
  };
@@ -68,6 +70,8 @@ async function main() {
68
70
 
69
71
  updateAstroConfig(targetDir, selectedFrameworks);
70
72
 
73
+ updateMultiAstroPage(targetDir, selectedFrameworks)
74
+
71
75
  const readmeSrc = path.resolve(__dirname, "../README.md");
72
76
  const readmeDest = path.join(targetDir, "README.md");
73
77
 
@@ -91,7 +95,10 @@ function copyDir(src, dest) {
91
95
  fs.mkdirSync(dest, { recursive: true });
92
96
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
93
97
  const srcPath = path.join(src, entry.name);
94
- const destPath = path.join(dest, entry.name);
98
+
99
+ // Check if the file is our renamed gitignore
100
+ const destName = entry.name === ".npmignore" ? ".gitignore" : entry.name;
101
+ const destPath = path.join(dest, destName);
95
102
 
96
103
  if (entry.isDirectory()) {
97
104
  copyDir(srcPath, destPath);
@@ -152,13 +159,21 @@ function updateAstroConfig(projectDir, selectedFrameworks) {
152
159
  import: /import\s+angular\s+from\s+['"]@analogjs\/astro-angular['"];\s*\n?/,
153
160
  integration: /angular\s*\(\s*\{[\s\S]*?\}\s*\)\s*,?\s*/
154
161
  },
162
+ preact: {
163
+ import: /import\s+preact\s+from\s+['"]@astrojs\/preact['"];\s*\n?/,
164
+ integration: /preact\s*\(\s*\{[\s\S]*?\}\s*\)\s*,?\s*/
165
+ },
155
166
  react: {
156
167
  import: /import\s+react\s+from\s+['"]@astrojs\/react['"];\s*\n?/,
157
- integration: /react\(\)\s*,?\s*/
168
+ integration: /react\s*\(\s*\{[\s\S]*?\}\s*\)\s*,?\s*/
169
+ },
170
+ svelte: {
171
+ import: /import\s+svelte\s+from\s+['"]@astrojs\/svelte['"];\s*\n?/,
172
+ integration: /svelte\s*\(\s*\{[\s\S]*?\}\s*\)\s*,?\s*/
158
173
  },
159
174
  vue: {
160
175
  import: /import\s+vue\s+from\s+['"]@astrojs\/vue['"];\s*\n?/,
161
- integration: /vue\(\)\s*,?\s*/
176
+ integration: /vue\s*\(\s*\{[\s\S]*?\}\s*\)\s*,?\s*/
162
177
  }
163
178
  };
164
179
 
@@ -183,6 +198,57 @@ function updateAstroConfig(projectDir, selectedFrameworks) {
183
198
  console.log("🛠️ Updated astro.config.mjs integrations");
184
199
  }
185
200
 
201
+ function updateMultiAstroPage(projectDir, selectedFrameworks) {
202
+ const pagePath = path.join(projectDir, "src", "pages", "multi", "store.astro");
203
+
204
+ if (!fs.existsSync(pagePath)) {
205
+ console.warn(`⚠️ ${path.relative(projectDir, pagePath)} not found, skipping page cleanup.`);
206
+ return;
207
+ }
208
+
209
+ let content = fs.readFileSync(pagePath, "utf-8");
210
+
211
+ // Map each framework to its specific Import and Component tag patterns
212
+ const frameworkMap = {
213
+ angular: {
214
+ import: /import\s+AngularStore\s+from\s+['"].*?angular\/Store\.component['"];?\s*\n?/g,
215
+ component: /<AngularStore\s+client:visible\s*\/>\s*\n?/g
216
+ },
217
+ preact: {
218
+ import: /import\s+PreactStore\s+from\s+['"].*?preact\/Store['"];?\s*\n?/g,
219
+ component: /<PreactStore\s+client:only="preact"\s*\/>\s*\n?/g
220
+ },
221
+ react: {
222
+ import: /import\s+ReactStore\s+from\s+['"].*?react\/Store['"];?\s*\n?/g,
223
+ component: /<ReactStore\s+client:only="react"\s*\/>\s*\n?/g
224
+ },
225
+ svelte: {
226
+ import: /import\s+SvelteStore\s+from\s+['"].*?svelte\/Store\.svelte['"];?\s*\n?/g,
227
+ component: /<SvelteStore\s+client:only="svelte"\s*\/>\s*\n?/g
228
+ },
229
+ vue: {
230
+ import: /import\s+VueStore\s+from\s+['"].*?vue\/Store\.vue['"];?\s*\n?/g,
231
+ component: /<VueStore\s+client:only="vue"\s*\/>\s*\n?/g
232
+ }
233
+ };
234
+
235
+ FRAMEWORKS.forEach(({ value: framework }) => {
236
+ if (!selectedFrameworks.includes(framework)) {
237
+ const patterns = frameworkMap[framework];
238
+ if (patterns) {
239
+ content = content.replace(patterns.import, "");
240
+ content = content.replace(patterns.component, "");
241
+ }
242
+ }
243
+ });
244
+
245
+ // Clean up any double-newlines left behind in the template body
246
+ content = content.replace(/\n\s*\n\s*\n/g, "\n\n");
247
+
248
+ fs.writeFileSync(pagePath, content, "utf-8");
249
+ console.log(`✨ Cleaned up components in ${path.relative(projectDir, pagePath)}`);
250
+ }
251
+
186
252
  function detectPackageManager() {
187
253
  if (typeof Deno !== "undefined") return "deno";
188
254
 
@@ -226,7 +292,7 @@ function packageInstall(targetDir) {
226
292
  yarn: "yarn",
227
293
  pnpm: "pnpm install",
228
294
  bun: "bun install",
229
- deno: "deno install && deno run postinsall",
295
+ deno: "deno install && deno run postinsall:deno",
230
296
  unknown: "npm install"
231
297
  }[packageManager];
232
298
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-outsystems-astro",
3
3
  "type": "module",
4
- "version": "0.5.0",
4
+ "version": "0.7.0",
5
5
  "description": "Create an OutSystems Astro Island project to import as a component into your OutSystems application",
6
6
  "repository": {
7
7
  "type": "git",
@@ -1,4 +1,5 @@
1
1
  .github/
2
+ .prettierrc
2
3
  bun.lock
3
4
  deno.json
4
5
  deno.lock
@@ -9,4 +10,5 @@ package-lock.json
9
10
  package.json
10
11
  patches/
11
12
  pnpm-lock.yaml
13
+ pnpm-workspace.yaml
12
14
  yarn.lock
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugins": ["prettier-plugin-svelte"],
3
+ "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
4
+ }
@@ -6,8 +6,10 @@
6
6
  - The output generation will be only client side. No server side rendering or server side components will be used.
7
7
  - The Astro Islands can be used generated with the following frameworks:
8
8
  - Angular - Documentation available at https://analogjs.org/docs/packages/astro-angular/overview
9
+ - Preact - Documentation available at https://docs.astro.build/en/guides/integrations-guide/preact/
9
10
  - React - Documentation available at https://docs.astro.build/en/guides/integrations-guide/react/
10
- - Vue - https://docs.astro.build/en/guides/integrations-guide/vue/
11
+ - Svelte - Documentation availabe at https://docs.astro.build/en/guides/integrations-guide/svelte/
12
+ - Vue - Documentation available at https://docs.astro.build/en/guides/integrations-guide/vue/
11
13
  - Prefer to use TypeScript when possible.
12
14
 
13
15
  ## OutSystems
@@ -28,17 +30,41 @@ In OutSystems 11, the Islands library is available at https://www.outsystems.com
28
30
 
29
31
  In OutSystems Developer Cloud, the Islands library is available at https://www.outsystems.com/forge/component-overview/22960/islands-odc.
30
32
 
33
+ - When starting a project, the demo files should be deleted. The demo files under src/ and test/.
34
+
31
35
  ### Pages
32
36
 
33
37
  - The files in src/pages/\*.astro are used as a starting point and holds the components for generation. They can be tested by running `npm run dev`. That will show what the component looks like as rendered. The sample example pages are broken out by framework name (src/pages/react, src/pages/vue, etc). This page will house the component(s) entry points.
34
- - When importing a component, the component must have the attribute of the client:only= + the framework name.
35
- - React: `client:only="react"`.
36
- - Vue: `client:only="vue"`.
37
- - Angular: `client:visible`.
38
+ - When importing a component, the component must have the attribute of the client:only= + the framework name.\
39
+ - Angular: `client:visible`
40
+ - Preact: `client:only="preact"`
41
+ - React: `client:only="react"`
42
+ - Svelte: `client:only="svelte"`
43
+ - Vue: `client:only="vue"`
38
44
 
39
45
  ### Components
40
46
 
41
- - The components live in the folder framework/{NAME}/ (src/framework/angular, src/framework/react and src/framework/vue ) with each framework having its own folder. The framework folder should stay in place as the components will be rendered from there. The Angular components will only be transformed by Astro if they are in the framework/angular folder.
47
+ - The components live in the folder framework/{NAME}/:
48
+ - Angular: src/framework/angular
49
+ - Preact: src/framework/react
50
+ - React: src/framework/react
51
+ - Svelte: src/framework/svelte
52
+ - Vue: src/framework/vue
53
+
54
+ The framework folder should stay in place as the components will be rendered from there. The Angular components will only be transformed by Astro if they are in the framework/angular folder.
55
+
56
+ - For any JSX based libraries, the @jsxImportSource directive must be at the top of the file.
57
+ - Preact:
58
+
59
+ ```js
60
+ /** @jsxImportSource preact */
61
+ ```
62
+
63
+ - React:
64
+
65
+ ```js
66
+ /** @jsxImportSource react */
67
+ ```
42
68
 
43
69
  ### Parameters
44
70
 
@@ -49,6 +75,58 @@ In OutSystems Developer Cloud, the Islands library is available at https://www.o
49
75
 
50
76
  Astro slots can be sent in. A slot can be either the default one or the named one. Each framework handles slots differently. Slots can only be HTML elements and cannot be components of a framework.
51
77
 
78
+ ##### Angular
79
+
80
+ Angular does not support the use of slots. Any use of slots with Angular should be discouraged.
81
+
82
+ ##### Preact
83
+
84
+ - In Preact, slots are handled as props. The default slot is the `children` prop. A named slot will have the name of its slot as the parameter. For example, a slot with the following:
85
+
86
+ ```js
87
+ <div slot="header">Header content</div>
88
+ ```
89
+
90
+ will have the parameter named header.
91
+
92
+ - The slots are then rendered using the regular React rendering parameter method. With the following Astro component:
93
+
94
+ ```js
95
+ ---
96
+ import CounterComponent from '../../framework/preact/Counter';
97
+ ---
98
+ <CounterComponent client:only="preact">
99
+ <div slot="header">
100
+ Counter Component
101
+ </div>
102
+ <div style="text-align: center;">
103
+ <p>This is content passed into the component.</p>
104
+ </div>
105
+ </CounterComponent>
106
+ ```
107
+
108
+ the slots can be used as:
109
+
110
+ ```js
111
+ export default function Counter({
112
+ children,
113
+ header,
114
+ }: {
115
+ children: ComponentChildren;
116
+ header: ComponentChildren;
117
+ }) {
118
+
119
+ return (
120
+ <>
121
+ {header}
122
+ <div>
123
+ {children}
124
+ </div>
125
+ </>
126
+ );
127
+ }
128
+ ```
129
+
52
130
  ##### React
53
131
 
54
132
  - In React, slots are handled as props. The default slot is the `children` prop. A named slot will have the name of its slot as the parameter. For example, a slot with the following:
@@ -67,10 +145,10 @@ import CounterComponent from '../../framework/react/Counter';
67
145
  ---
68
146
  <CounterComponent client:only="react">
69
147
  <div slot="header">
70
- Counter
148
+ Counter Component
71
149
  </div>
72
150
  <div style="text-align: center;">
73
- <p>Slot content!</p>
151
+ <p>This is content passed into the component.</p>
74
152
  </div>
75
153
  </CounterComponent>
76
154
  ```
@@ -97,6 +175,31 @@ export default function Counter({
97
175
  }
98
176
  ```
99
177
 
178
+ ##### Svelte
179
+
180
+ - In Svelte, slots are handled as by using the <slot /> tag. The default slot is the is just <slot />. A named slot will have the name of its slot as an attribute such as <slot name="header" />. Placement of the slot will determine where the slot will render.
181
+
182
+ ```js
183
+ ---
184
+ import CounterComponent from "../../framework/svelte/Counter.svelte";
185
+ ---
186
+ <CounterComponent client:only="svelte">
187
+ <div class="counter-title" slot="header">Counter Component</div>
188
+ <div style="text-align: center;">
189
+ <p><strong>This is content passed into the component.</strong></p>
190
+ </div>
191
+ </CounterComponent>
192
+ ```
193
+
194
+ the slots can be used as:
195
+
196
+ ```svelte
197
+ <slot name="header" />
198
+ <div>
199
+ <slot />
200
+ </div>
201
+ ```
202
+
100
203
  ##### Vue
101
204
 
102
205
  - In Vue, slots are handled as by using the <slot /> tag. The default slot is the is just <slot />. A named slot will have the name of its slot as an attribute such as <slot name="header" />. Placement of the slot will determine where the slot will render.
@@ -107,10 +210,10 @@ import CounterComponent from '../../framework/react/Counter';
107
210
  ---
108
211
  <CounterComponent client:only="vue">
109
212
  <div slot="header">
110
- Counter
213
+ Counter Component
111
214
  </div>
112
215
  <div style="text-align: center;">
113
- <p>Slot content!</p>
216
+ <p>This is content passed into the component.</p>
114
217
  </div>
115
218
  </CounterComponent>
116
219
  ```
@@ -126,10 +229,6 @@ the slots can be used as:
126
229
  </template>
127
230
  ```
128
231
 
129
- ##### Angular
130
-
131
- Angular does not support the use of slots. Any use of slots with Angular should be discouraged.
132
-
133
232
  ### Nano Stores
134
233
 
135
234
  The Nano Stores library - https://github.com/nanostores/nanostores - is supported for both sharing state between different Islands or from OutSystems to an Island. This could be used in place of a parameter, but parameters should be the default method.
@@ -140,15 +239,14 @@ The OutSystems 11 library is called Lightweight State Manager - https://www.outs
140
239
 
141
240
  The OutSystems Developer Cloud library is called Lightweight State Manager and is available in the ODC Forge.
142
241
 
143
- Nano Stores are currently supported for only React - https://github.com/nanostores/react and Vue - https://github.com/nanostores/vue. The Angular 21 library does not yet support them.
242
+ Nano Stores are currently supported for only Preact - https://github.com/nanostores/preact, React - https://github.com/nanostores/react and Vue - https://github.com/nanostores/vue. The Angular 21 library does not yet support them.
144
243
 
145
244
  In OutSystems, the store will be on the Window object. The Islands component will then have to access it from there.
146
245
 
147
- #### React
246
+ #### Preact
148
247
 
149
- ```js
150
- import { useStore } from "@nanostores/react";
151
- import { useState } from "react";
248
+ ```jsx
249
+ import { useStore } from "@nanostores/preact";
152
250
 
153
251
  export default function Counter({}) {
154
252
  const nanoStoreValue = useStore(window.Stores["MyGreatStore"]);
@@ -164,6 +262,33 @@ export default function Counter({}) {
164
262
  }
165
263
  ```
166
264
 
265
+ #### React
266
+
267
+ ```jsx
268
+ import { useStore } from "@nanostores/react";
269
+ import { useState } from "react";
270
+
271
+ export default function Counter({}) {
272
+ const nanoStoreValue = useStore(window.Stores["MyGreatStore"]);
273
+
274
+ return (
275
+ <>
276
+ <div>{nanoStoreValue}</div>
277
+ </>
278
+ );
279
+ }
280
+ ```
281
+
282
+ #### Svelte
283
+
284
+ ```svelte
285
+ <script lang="ts">
286
+ const nanoStoreValue = (window as any).Stores["svelteStore"];
287
+ </script>
288
+
289
+ <div>{$nanoStoreValue}</div>
290
+ ```
291
+
167
292
  #### Vue
168
293
 
169
294
  ```vue
@@ -173,9 +298,7 @@ const nanoStoreValue = useStore(window.Stores["MyGreatStore"]);
173
298
  </script>
174
299
 
175
300
  <template>
176
- <div>
177
- <div>{{ nanoStoreValue }}</div>
178
- </div>
301
+ <div>{{ nanoStoreValue }}</div>
179
302
  </template>
180
303
  ```
181
304
 
@@ -1,6 +1,8 @@
1
1
  // @ts-check
2
2
  import angular from "@analogjs/astro-angular";
3
+ import preact from "@astrojs/preact";
3
4
  import react from "@astrojs/react";
5
+ import svelte from "@astrojs/svelte";
4
6
  import vue from "@astrojs/vue";
5
7
  import { defineConfig } from "astro/config";
6
8
 
@@ -17,8 +19,19 @@ export default defineConfig({
17
19
  },
18
20
  },
19
21
  }),
20
- react(),
21
- vue(),
22
+ preact({
23
+ compat: true,
24
+ include: ["src/framework/preact/*"],
25
+ }),
26
+ react({
27
+ include: ["src/framework/react/*"],
28
+ }),
29
+ svelte({
30
+ include: ["src/framework/svelte/*"],
31
+ }),
32
+ vue({
33
+ include: ["src/framework/vue/*"],
34
+ }),
22
35
  ],
23
36
  server: {
24
37
  host: true,