actionview-svelte-handler 0.3.0 → 0.5.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.
data/lib/ts/builder.ts ADDED
@@ -0,0 +1,175 @@
1
+ import { readable, Stores } from 'svelte/store'
2
+ import { importFromStringSync } from 'module-from-string'
3
+ import * as esbuild from 'esbuild'
4
+ import sveltePlugin from 'esbuild-svelte'
5
+ import { sveltePreprocess } from 'svelte-preprocess'
6
+ import type { Warning } from 'svelte/types/compiler/interfaces'
7
+ import * as recast from 'recast'
8
+
9
+ export interface BuildSuccess {
10
+ client: string
11
+ server: {
12
+ html: string
13
+ css: string
14
+ head: string
15
+ } | null
16
+ compiled: {
17
+ client: string
18
+ server: string | undefined
19
+ }
20
+ }
21
+
22
+ export interface BuildError {
23
+ error: any
24
+ }
25
+
26
+ export type BuildResult = BuildSuccess | BuildError
27
+
28
+ /**
29
+ * Builder is a class that builds, compiles and bundles Svelte components into a nice object for the template handler
30
+ */
31
+ class Builder {
32
+ path: string
33
+ props: Stores
34
+ locals: object
35
+ compiled: {
36
+ client: string | null
37
+ server: string | null
38
+ }
39
+
40
+ ssr: boolean
41
+ workingDir: string
42
+ preprocess: object
43
+
44
+ constructor (
45
+ path: string,
46
+ props: object,
47
+ locals: object,
48
+ client: string | null,
49
+ server: string | null,
50
+ ssr: boolean,
51
+ workingDir: string,
52
+ preprocess: object
53
+ ) {
54
+ this.path = path
55
+ this.props = readable(props)
56
+ this.locals = locals
57
+ this.compiled = {
58
+ client,
59
+ server
60
+ }
61
+ this.ssr = ssr
62
+ this.workingDir = workingDir
63
+ this.preprocess = preprocess
64
+ }
65
+
66
+ async bundle (generate: 'ssr' | 'dom', sveltePath = 'svelte'): Promise<string> {
67
+ const bundle = await esbuild.build({
68
+ entryPoints: [this.path],
69
+ mainFields: ['svelte', 'browser', 'module', 'main'],
70
+ conditions: ['svelte', 'browser'],
71
+ absWorkingDir: this.workingDir,
72
+ write: false,
73
+ outfile: 'component.js',
74
+ bundle: true,
75
+ format: 'esm',
76
+ metafile: true,
77
+ plugins: [
78
+ // @ts-expect-error
79
+ sveltePlugin({
80
+ compilerOptions: {
81
+ generate,
82
+ css: 'injected',
83
+ hydratable: true,
84
+ sveltePath
85
+ },
86
+ preprocess: sveltePreprocess(this.preprocess),
87
+ filterWarnings: (warning: Warning) => {
88
+ if (
89
+ warning.code === 'missing-declaration' &&
90
+ warning.message.includes("'props'")
91
+ ) {
92
+ return false
93
+ }
94
+ return true
95
+ }
96
+ })
97
+ ]
98
+ })
99
+
100
+ // @ts-expect-error
101
+ const throwables = [].concat(bundle.errors, bundle.warnings)
102
+
103
+ if (throwables.length > 0) {
104
+ throw throwables[0] // eslint-disable-line @typescript-eslint/no-throw-literal
105
+ }
106
+
107
+ return bundle.outputFiles[0].text
108
+ }
109
+
110
+ async client (): Promise<string> {
111
+ return (
112
+ this.compiled?.client || (this.standardizeClient(await this.bundle('dom', 'https://esm.sh/svelte'))) // eslint-disable-line
113
+ )
114
+ }
115
+
116
+ standardizeClient (code: string): string {
117
+ const ast = recast.parse(code)
118
+
119
+ let name: string | undefined
120
+
121
+ recast.visit(ast, {
122
+ visitExportNamedDeclaration: (path) => {
123
+ const stagingName: any = path.node?.specifiers?.[0].local?.name
124
+ name = typeof stagingName !== 'string' ? '' : stagingName
125
+ path.prune()
126
+ return false
127
+ }
128
+ })
129
+
130
+ recast.visit(ast, {
131
+ visitIdentifier: (path) => {
132
+ if (path.node.name === name) {
133
+ path.node.name = 'App'
134
+ }
135
+ return false
136
+ }
137
+ })
138
+
139
+ return recast.print(ast).code
140
+ }
141
+
142
+ async server (): Promise<{ output: string, html: string, css: string, head: string }> {
143
+ const output = this.compiled?.server || (await this.bundle('ssr')) // eslint-disable-line
144
+
145
+ const Component = importFromStringSync(output, {
146
+ globals: { props: this.props }
147
+ }).default
148
+
149
+ const { html, css, head } = await Component.render(this.locals)
150
+
151
+ return { output, html, head, css: css.code }
152
+ }
153
+
154
+ async build (): Promise<BuildResult> {
155
+ try {
156
+ const serv = this.ssr ? await this.server() : null
157
+ const cli = await this.client()
158
+
159
+ const comp = {
160
+ client: cli,
161
+ server: serv?.output
162
+ }
163
+
164
+ return {
165
+ client: cli,
166
+ server: serv,
167
+ compiled: comp
168
+ }
169
+ } catch (e) {
170
+ return { error: e }
171
+ }
172
+ }
173
+ }
174
+
175
+ export default Builder
@@ -0,0 +1,2 @@
1
+ > [!CAUTION]
2
+ > This folder is intended to be built from TypeScript files with `npm run build`
@@ -0,0 +1,44 @@
1
+ import { Stores } from 'svelte/store';
2
+ export interface BuildSuccess {
3
+ client: string;
4
+ server: {
5
+ html: string;
6
+ css: string;
7
+ head: string;
8
+ } | null;
9
+ compiled: {
10
+ client: string;
11
+ server: string | undefined;
12
+ };
13
+ }
14
+ export interface BuildError {
15
+ error: any;
16
+ }
17
+ export type BuildResult = BuildSuccess | BuildError;
18
+ /**
19
+ * Builder is a class that builds, compiles and bundles Svelte components into a nice object for the template handler
20
+ */
21
+ declare class Builder {
22
+ path: string;
23
+ props: Stores;
24
+ locals: object;
25
+ compiled: {
26
+ client: string | null;
27
+ server: string | null;
28
+ };
29
+ ssr: boolean;
30
+ workingDir: string;
31
+ preprocess: object;
32
+ constructor(path: string, props: object, locals: object, client: string | null, server: string | null, ssr: boolean, workingDir: string, preprocess: object);
33
+ bundle(generate: 'ssr' | 'dom', sveltePath?: string): Promise<string>;
34
+ client(): Promise<string>;
35
+ standardizeClient(code: string): string;
36
+ server(): Promise<{
37
+ output: string;
38
+ html: string;
39
+ css: string;
40
+ head: string;
41
+ }>;
42
+ build(): Promise<BuildResult>;
43
+ }
44
+ export default Builder;