@agnos-ui/svelte-preprocess 0.3.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 ADDED
@@ -0,0 +1,65 @@
1
+ # @agnos-ui/svelte-preprocess
2
+
3
+ [![npm](https://img.shields.io/npm/v/@agnos-ui/svelte-preprocess)](https://www.npmjs.com/package/@agnos-ui/svelte-preprocess)
4
+
5
+ Preprocessor to run [Svelte](https://svelte.dev/) [actions](https://svelte.dev/docs/svelte-action) server-side, which are called [directives](https://amadeusitgroup.github.io/AgnosUI/latest/docs/angular/headless/directives) in AgnosUI.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @agnos-ui/svelte-preprocess
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Add the `directivesPreprocess()` preprocessor to your `svelte.config.js`:
16
+
17
+ ```js
18
+ import {directivesPreprocess} from '@agnos-ui/svelte-preprocess';
19
+
20
+ // ...
21
+
22
+ /** @type {import('@sveltejs/kit').Config} */
23
+ const config = {
24
+ // ...
25
+
26
+ // Consult https://kit.svelte.dev/docs/integrations#preprocessors
27
+ // for more information about preprocessors
28
+ preprocess: [
29
+ // ... existing preprocessors
30
+
31
+ // Add the following line:
32
+ directivesPreprocess(),
33
+ ],
34
+
35
+ // ...
36
+ };
37
+
38
+ export default config;
39
+ ```
40
+
41
+ Given the following file:
42
+
43
+ ```svelte
44
+ <script>
45
+ import {myDirective} from './myDirective';
46
+ </script>
47
+
48
+ <div use:myDirective></div>
49
+ ```
50
+
51
+ The preprocessor will transform it into something like:
52
+
53
+ ```svelte
54
+ <script>
55
+ import {ssrAttributes} from '@agnos-ui/svelte-headless/utils/directive';
56
+ import {BROWSER} from 'esm-env';
57
+ import {myDirective} from './myDirective';
58
+ </script>
59
+
60
+ <div use:myDirective {...BROWSER ? {} : ssrAttributes(myDirective)}></div>
61
+ ```
62
+
63
+ On the server, `ssrAttributes` runs all the provided directives with an [`SSRHTMLElement`](https://github.com/AmadeusITGroup/AgnosUI/blob/ffc1339eb60e02e07d3415efd3f6fac890c8a39d/core/src/types.ts#L94) that implements a subset of the full [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). The attributes added by the directives on this element are returned by `ssrAttributes` to be included in the SSR-generated markup.
64
+
65
+ If the element has a `class` attribute, the preprocessor will replace it with the `classDirective` directive to make sure the value of the class attribute is correctly merged both on the server and on the client with any other class that may be added by some other directive.
package/index.cjs ADDED
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const MagicString = require("magic-string");
4
+ const compiler = require("svelte/compiler");
5
+ const directivesPreprocess = () => {
6
+ return {
7
+ name: "AgnosUI",
8
+ markup: async ({ content, filename }) => {
9
+ const varPrefix = "__AgnosUISveltePreprocess__";
10
+ if (content.includes(varPrefix)) {
11
+ return;
12
+ }
13
+ const str = new MagicString(content, { filename });
14
+ const parsedCode = compiler.parse(content, { filename });
15
+ const requiredImports = /* @__PURE__ */ new Set();
16
+ const extractValue = (attribute) => {
17
+ const res = [];
18
+ const value = attribute.value;
19
+ for (const part of value) {
20
+ if (part.type === "Text") {
21
+ res.push(JSON.stringify(part.data));
22
+ } else if (part.type === "MustacheTag") {
23
+ res.push(`(${content.substring(part.expression.start, part.expression.end)})`);
24
+ } else {
25
+ throw new Error(`Unexpected part type: ${part.type}`);
26
+ }
27
+ }
28
+ return res.join("+");
29
+ };
30
+ const processItem = (item) => {
31
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
32
+ const actionAttributes = [];
33
+ const classAttributes = [];
34
+ if (item.attributes) {
35
+ for (const attribute of item.attributes) {
36
+ if (attribute.type === "Action") {
37
+ actionAttributes.push(attribute);
38
+ } else if (attribute.type === "Attribute" && attribute.name === "class") {
39
+ classAttributes.push(attribute);
40
+ }
41
+ }
42
+ if (actionAttributes.length > 0) {
43
+ const end = item.attributes[item.attributes.length - 1].end;
44
+ let first = true;
45
+ str.appendRight(end, ` {...${varPrefix}BROWSER ? {} : ${varPrefix}ssrAttributes(`);
46
+ requiredImports.add("ssrAttributes");
47
+ for (const attribute of actionAttributes) {
48
+ if (first) {
49
+ first = false;
50
+ } else {
51
+ str.appendRight(end, `, `);
52
+ }
53
+ if (attribute.expression) {
54
+ str.appendRight(end, `[${attribute.name}, ${content.substring(attribute.expression.start, attribute.expression.end)}]`);
55
+ } else {
56
+ str.appendRight(end, attribute.name);
57
+ }
58
+ }
59
+ for (const attribute of classAttributes) {
60
+ const value = extractValue(attribute);
61
+ str.overwrite(attribute.start, attribute.end, `use:${varPrefix}classDirective={${value}}`);
62
+ str.appendRight(end, `, [${varPrefix}classDirective, ${value}]`);
63
+ requiredImports.add("classDirective");
64
+ }
65
+ str.appendRight(end, `)}`);
66
+ }
67
+ }
68
+ (_a = item.children) == null ? void 0 : _a.forEach(processItem);
69
+ (_c = (_b = item.else) == null ? void 0 : _b.children) == null ? void 0 : _c.forEach(processItem);
70
+ (_e = (_d = item.pending) == null ? void 0 : _d.children) == null ? void 0 : _e.forEach(processItem);
71
+ (_g = (_f = item.then) == null ? void 0 : _f.children) == null ? void 0 : _g.forEach(processItem);
72
+ (_i = (_h = item.catch) == null ? void 0 : _h.children) == null ? void 0 : _i.forEach(processItem);
73
+ };
74
+ processItem(parsedCode.html);
75
+ if (requiredImports.size > 0) {
76
+ const importStatement = `
77
+ import {${[...requiredImports].map((importName) => `${importName} as ${varPrefix}${importName}`).join(", ")}} from '@agnos-ui/svelte-headless/utils/directive';
78
+ import {BROWSER as ${varPrefix}BROWSER} from 'esm-env';
79
+ `;
80
+ const moduleOrInstance = parsedCode.module ?? parsedCode.instance;
81
+ if (moduleOrInstance) {
82
+ const start = content.indexOf(">", moduleOrInstance.start) + 1;
83
+ str.prependLeft(start, importStatement);
84
+ } else {
85
+ str.prepend(`<script>${importStatement}<\/script>
86
+ `);
87
+ }
88
+ }
89
+ return {
90
+ code: str.toString(),
91
+ map: str.generateMap()
92
+ };
93
+ }
94
+ };
95
+ };
96
+ exports.directivesPreprocess = directivesPreprocess;
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ /// <reference types="svelte" />
2
+ import type { PreprocessorGroup } from 'svelte/compiler';
3
+ export declare const directivesPreprocess: () => PreprocessorGroup;
package/index.js ADDED
@@ -0,0 +1,96 @@
1
+ import MagicString from "magic-string";
2
+ import { parse } from "svelte/compiler";
3
+ const directivesPreprocess = () => {
4
+ return {
5
+ name: "AgnosUI",
6
+ markup: async ({ content, filename }) => {
7
+ const varPrefix = "__AgnosUISveltePreprocess__";
8
+ if (content.includes(varPrefix)) {
9
+ return;
10
+ }
11
+ const str = new MagicString(content, { filename });
12
+ const parsedCode = parse(content, { filename });
13
+ const requiredImports = /* @__PURE__ */ new Set();
14
+ const extractValue = (attribute) => {
15
+ const res = [];
16
+ const value = attribute.value;
17
+ for (const part of value) {
18
+ if (part.type === "Text") {
19
+ res.push(JSON.stringify(part.data));
20
+ } else if (part.type === "MustacheTag") {
21
+ res.push(`(${content.substring(part.expression.start, part.expression.end)})`);
22
+ } else {
23
+ throw new Error(`Unexpected part type: ${part.type}`);
24
+ }
25
+ }
26
+ return res.join("+");
27
+ };
28
+ const processItem = (item) => {
29
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
30
+ const actionAttributes = [];
31
+ const classAttributes = [];
32
+ if (item.attributes) {
33
+ for (const attribute of item.attributes) {
34
+ if (attribute.type === "Action") {
35
+ actionAttributes.push(attribute);
36
+ } else if (attribute.type === "Attribute" && attribute.name === "class") {
37
+ classAttributes.push(attribute);
38
+ }
39
+ }
40
+ if (actionAttributes.length > 0) {
41
+ const end = item.attributes[item.attributes.length - 1].end;
42
+ let first = true;
43
+ str.appendRight(end, ` {...${varPrefix}BROWSER ? {} : ${varPrefix}ssrAttributes(`);
44
+ requiredImports.add("ssrAttributes");
45
+ for (const attribute of actionAttributes) {
46
+ if (first) {
47
+ first = false;
48
+ } else {
49
+ str.appendRight(end, `, `);
50
+ }
51
+ if (attribute.expression) {
52
+ str.appendRight(end, `[${attribute.name}, ${content.substring(attribute.expression.start, attribute.expression.end)}]`);
53
+ } else {
54
+ str.appendRight(end, attribute.name);
55
+ }
56
+ }
57
+ for (const attribute of classAttributes) {
58
+ const value = extractValue(attribute);
59
+ str.overwrite(attribute.start, attribute.end, `use:${varPrefix}classDirective={${value}}`);
60
+ str.appendRight(end, `, [${varPrefix}classDirective, ${value}]`);
61
+ requiredImports.add("classDirective");
62
+ }
63
+ str.appendRight(end, `)}`);
64
+ }
65
+ }
66
+ (_a = item.children) == null ? void 0 : _a.forEach(processItem);
67
+ (_c = (_b = item.else) == null ? void 0 : _b.children) == null ? void 0 : _c.forEach(processItem);
68
+ (_e = (_d = item.pending) == null ? void 0 : _d.children) == null ? void 0 : _e.forEach(processItem);
69
+ (_g = (_f = item.then) == null ? void 0 : _f.children) == null ? void 0 : _g.forEach(processItem);
70
+ (_i = (_h = item.catch) == null ? void 0 : _h.children) == null ? void 0 : _i.forEach(processItem);
71
+ };
72
+ processItem(parsedCode.html);
73
+ if (requiredImports.size > 0) {
74
+ const importStatement = `
75
+ import {${[...requiredImports].map((importName) => `${importName} as ${varPrefix}${importName}`).join(", ")}} from '@agnos-ui/svelte-headless/utils/directive';
76
+ import {BROWSER as ${varPrefix}BROWSER} from 'esm-env';
77
+ `;
78
+ const moduleOrInstance = parsedCode.module ?? parsedCode.instance;
79
+ if (moduleOrInstance) {
80
+ const start = content.indexOf(">", moduleOrInstance.start) + 1;
81
+ str.prependLeft(start, importStatement);
82
+ } else {
83
+ str.prepend(`<script>${importStatement}<\/script>
84
+ `);
85
+ }
86
+ }
87
+ return {
88
+ code: str.toString(),
89
+ map: str.generateMap()
90
+ };
91
+ }
92
+ };
93
+ };
94
+ export {
95
+ directivesPreprocess
96
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@agnos-ui/svelte-preprocess",
3
+ "description": "Preprocessor to run Svelte directives server-side.",
4
+ "version": "0.3.0",
5
+ "type": "module",
6
+ "main": "./index.cjs",
7
+ "module": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "require": "./index.cjs",
13
+ "default": "./index.js"
14
+ }
15
+ },
16
+ "dependencies": {
17
+ "magic-string": "^0.30.10"
18
+ },
19
+ "peerDependencies": {
20
+ "svelte": "*"
21
+ },
22
+ "sideEffects": false,
23
+ "homepage": "https://amadeusitgroup.github.io/AgnosUI/latest/",
24
+ "bugs": "https://github.com/AmadeusITGroup/AgnosUI/issues",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/AmadeusITGroup/AgnosUI.git",
29
+ "directory": "svelte/preprocess"
30
+ },
31
+ "keywords": [
32
+ "svelte",
33
+ "AgnosUI",
34
+ "accordion",
35
+ "alert",
36
+ "components",
37
+ "modal",
38
+ "pagination",
39
+ "progressbar",
40
+ "rating",
41
+ "slider",
42
+ "toast",
43
+ "widgets"
44
+ ]
45
+ }