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.
- checksums.yaml +4 -4
- data/.forgejo/workflows/javascript_police.yml +22 -0
- data/.forgejo/workflows/ruby_police.yml +27 -0
- data/.gitignore +14 -0
- data/.ruby-version +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +284 -0
- data/README.md +90 -15
- data/Steepfile +12 -0
- data/actionview-svelte-handler.gemspec +21 -0
- data/bin/test +5 -0
- data/build.esbuild.js +22 -0
- data/lib/generators/svelte/install_generator.rb +13 -0
- data/lib/generators/svelte/templates/install/initializer.rb +17 -0
- data/lib/svelte/errors.rb +151 -0
- data/lib/svelte/handler.rb +51 -21
- data/lib/svelte/helpers.rb +14 -5
- data/lib/svelte/js/.DO_NOT_MODIFY.md +2 -0
- data/lib/svelte/js/builder.js +122 -0
- data/lib/svelte/railtie.rb +7 -5
- data/lib/svelte/templates/assembler.js.erb +16 -0
- data/lib/svelte/templates/island.html.erb +20 -0
- data/lib/svelte/variabilization.rb +11 -0
- data/lib/svelte/version.rb +1 -1
- data/lib/svelte.rb +27 -4
- data/lib/tasks/svelte_tasks.rake +4 -0
- data/lib/ts/builder.ts +175 -0
- data/lib/ts/types/.DO_NOT_MODIFY.md +2 -0
- data/lib/ts/types/builder.d.ts +44 -0
- data/package-lock.json +6643 -0
- data/package.json +39 -0
- data/rbs_collection.lock.yaml +344 -0
- data/rbs_collection.yaml +18 -0
- data/sig/lib/svelte/errors.rbs +38 -0
- data/sig/lib/svelte/handler.rbs +9 -0
- data/sig/lib/svelte/helpers.rbs +7 -0
- data/sig/lib/svelte/version.rbs +3 -0
- data/sig/lib/svelte.rbs +19 -0
- data/svelte-on-rails.png +0 -0
- data/tsconfig.json +15 -0
- data/watch.esbuild.js +4 -0
- metadata +37 -3
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,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;
|