firefly-compiler 0.4.78 → 0.4.79
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/.hintrc +4 -4
- package/.vscode/settings.json +4 -4
- package/bin/Release.ff +153 -153
- package/bin/firefly.mjs +1 -1
- package/compiler/Builder.ff +257 -257
- package/compiler/Compiler.ff +227 -227
- package/compiler/Dependencies.ff +187 -187
- package/compiler/DependencyLock.ff +17 -17
- package/compiler/JsEmitter.ff +946 -946
- package/compiler/LspHook.ff +202 -202
- package/compiler/ModuleCache.ff +178 -178
- package/compiler/Workspace.ff +88 -88
- package/core/.firefly/include/package-lock.json +564 -394
- package/core/.firefly/include/package.json +5 -5
- package/core/.firefly/include/prepare.sh +1 -1
- package/core/.firefly/package.ff +2 -2
- package/core/Array.ff +265 -265
- package/core/Atomic.ff +64 -64
- package/core/Box.ff +7 -7
- package/core/BrowserSystem.ff +40 -40
- package/core/BuildSystem.ff +148 -148
- package/core/Crypto.ff +96 -96
- package/core/Equal.ff +36 -36
- package/core/HttpClient.ff +148 -148
- package/core/JsSystem.ff +69 -69
- package/core/Json.ff +434 -434
- package/core/List.ff +486 -486
- package/core/Lock.ff +144 -144
- package/core/NodeSystem.ff +216 -216
- package/core/Ordering.ff +161 -161
- package/core/Path.ff +401 -401
- package/core/Random.ff +134 -134
- package/core/RbMap.ff +216 -216
- package/core/Show.ff +43 -43
- package/core/SourceLocation.ff +68 -68
- package/core/Task.ff +141 -141
- package/experimental/benchmarks/ListGrab.ff +23 -23
- package/experimental/benchmarks/ListGrab.java +55 -55
- package/experimental/benchmarks/Pyrotek45.ff +30 -30
- package/experimental/benchmarks/Pyrotek45.java +64 -64
- package/experimental/bidirectional/Bidi.ff +88 -88
- package/experimental/random/Index.ff +53 -53
- package/experimental/random/Process.ff +120 -120
- package/experimental/random/Scrape.ff +51 -51
- package/experimental/random/Symbols.ff +73 -73
- package/experimental/random/Tensor.ff +52 -52
- package/experimental/random/Units.ff +36 -36
- package/experimental/s3/S3TestAuthorizationHeader.ff +39 -38
- package/experimental/s3/S3TestPut.ff +16 -15
- package/experimental/tests/TestJson.ff +26 -26
- package/firefly.sh +0 -0
- package/fireflysite/.firefly/package.ff +4 -4
- package/fireflysite/CommunityOverview.ff +20 -20
- package/fireflysite/CountingButtonDemo.ff +58 -58
- package/fireflysite/DocumentParser.ff +218 -0
- package/fireflysite/ExamplesOverview.ff +40 -31
- package/fireflysite/FrontPage.ff +360 -0
- package/fireflysite/Guide.ff +411 -308
- package/fireflysite/GuideAll.ff +21 -0
- package/fireflysite/GuideBaseTypes.ff +168 -0
- package/fireflysite/GuideControlFlow.ff +212 -0
- package/fireflysite/GuideIntroduction.ff +52 -69
- package/fireflysite/Main.ff +137 -92
- package/fireflysite/MatchingPasswordsDemo.ff +82 -86
- package/fireflysite/PackagesOverview.ff +49 -49
- package/fireflysite/PostgresqlDemo.ff +34 -0
- package/fireflysite/Styles.ff +495 -306
- package/fireflysite/assets/NotoSansMono-Regular.ttf +0 -0
- package/fireflysite/assets/NunitoSans-VariableFont_YTLC,opsz,wdth,wght.ttf +0 -0
- package/fireflysite/assets/autocomplete-small.png +0 -0
- package/fireflysite/assets/autocomplete.png +0 -0
- package/fireflysite/assets/edit-time-error.png +0 -0
- package/fireflysite/assets/firefly-logo-yellow.png +0 -0
- package/fireflysite/assets/markdown/ControlFlow.md +136 -0
- package/fireflysite/assets/markdown/Example.md +78 -0
- package/lsp/.firefly/package.ff +1 -1
- package/lsp/CompletionHandler.ff +828 -828
- package/lsp/Handler.ff +714 -714
- package/lsp/HoverHandler.ff +79 -79
- package/lsp/LanguageServer.ff +272 -272
- package/lsp/SignatureHelpHandler.ff +55 -55
- package/lsp/SymbolHandler.ff +181 -181
- package/lsp/TestReferences.ff +17 -17
- package/lsp/TestReferencesCase.ff +7 -7
- package/lsp/stderr.txt +1 -1
- package/lsp/stdout.txt +34 -34
- package/lux/.firefly/package.ff +1 -1
- package/lux/Css.ff +648 -648
- package/lux/CssTest.ff +48 -48
- package/lux/Lux.ff +487 -487
- package/lux/LuxEvent.ff +116 -116
- package/lux/Main.ff +123 -123
- package/lux/Main2.ff +143 -143
- package/output/js/ff/compiler/Builder.mjs +43 -43
- package/output/js/ff/compiler/Dependencies.mjs +3 -3
- package/output/js/ff/core/Array.mjs +59 -59
- package/output/js/ff/core/Atomic.mjs +36 -36
- package/output/js/ff/core/BrowserSystem.mjs +11 -11
- package/output/js/ff/core/BuildSystem.mjs +30 -30
- package/output/js/ff/core/Crypto.mjs +40 -40
- package/output/js/ff/core/HttpClient.mjs +56 -56
- package/output/js/ff/core/Json.mjs +147 -147
- package/output/js/ff/core/List.mjs +50 -50
- package/output/js/ff/core/Lock.mjs +97 -97
- package/output/js/ff/core/NodeSystem.mjs +83 -83
- package/output/js/ff/core/Ordering.mjs +8 -8
- package/output/js/ff/core/Path.mjs +231 -231
- package/output/js/ff/core/Random.mjs +56 -56
- package/output/js/ff/core/Task.mjs +31 -31
- package/package.json +1 -1
- package/rpc/.firefly/package.ff +1 -1
- package/rpc/Rpc.ff +70 -70
- package/s3/.firefly/package.ff +1 -1
- package/s3/S3.ff +94 -94
- package/unsafejs/UnsafeJs.ff +19 -19
- package/vscode/LICENSE.txt +21 -21
- package/vscode/Prepublish.ff +15 -15
- package/vscode/README.md +16 -16
- package/vscode/client/package.json +22 -22
- package/vscode/client/src/extension.ts +104 -104
- package/vscode/icons/firefly-icon.svg +10 -10
- package/vscode/language-configuration.json +61 -61
- package/vscode/package-lock.json +3623 -3623
- package/vscode/package.json +15 -1
- package/vscode/snippets.json +241 -241
- package/vscode/syntaxes/firefly-markdown-injection.json +45 -0
- package/webserver/.firefly/include/package-lock.json +22 -16
- package/webserver/.firefly/include/package.json +5 -5
- package/webserver/.firefly/package.ff +2 -2
- package/webserver/WebServer.ff +685 -685
- package/websocket/.firefly/package.ff +1 -1
- package/websocket/WebSocket.ff +131 -131
- /package/fireflysite/{firefly-logo-notext.png → assets/firefly-logo-notext.png} +0 -0
package/core/Path.ff
CHANGED
|
@@ -1,401 +1,401 @@
|
|
|
1
|
-
capability Path {}
|
|
2
|
-
capability PathEntry {}
|
|
3
|
-
|
|
4
|
-
extend self: Path {
|
|
5
|
-
|
|
6
|
-
exists(checkReadable: Bool = False, checkWritable: Bool = False, checkExecutable: Bool = False): Bool
|
|
7
|
-
target node async """
|
|
8
|
-
import * as fs from 'fs'
|
|
9
|
-
import * as fsPromises from 'fs/promises'
|
|
10
|
-
const flags =
|
|
11
|
-
(fs.constants.R_OK * checkReadable_) |
|
|
12
|
-
(fs.constants.W_OK * checkWritable_) |
|
|
13
|
-
(fs.constants.X_OK * checkExecutable_)
|
|
14
|
-
try {
|
|
15
|
-
await fsPromises.access(self_, flags === 0 ? fs.constants.F_OK : flags)
|
|
16
|
-
return true
|
|
17
|
-
} catch(e) {
|
|
18
|
-
return false
|
|
19
|
-
}
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
isReadable(): Bool {
|
|
23
|
-
self.exists(checkReadable = True)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
isWritable(): Bool {
|
|
27
|
-
self.exists(checkWritable = True)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
isExecutable(): Bool {
|
|
31
|
-
self.exists(checkExecutable = True)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
isDirectory(): Bool
|
|
35
|
-
target node async """
|
|
36
|
-
import * as fsPromises from 'fs/promises'
|
|
37
|
-
try {
|
|
38
|
-
return (await fsPromises.lstat(self_)).isDirectory();
|
|
39
|
-
} catch(e) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
isFile(): Bool
|
|
45
|
-
target node async """
|
|
46
|
-
import * as fsPromises from 'fs/promises'
|
|
47
|
-
try {
|
|
48
|
-
return (await fsPromises.lstat(self_)).isFile();
|
|
49
|
-
} catch(e) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
isSymbolicLink(): Bool
|
|
55
|
-
target node async """
|
|
56
|
-
import * as fsPromises from 'fs/promises'
|
|
57
|
-
try {
|
|
58
|
-
return (await fsPromises.lstat(self_)).isSymbolicLink();
|
|
59
|
-
} catch(e) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
isInsideOf(path: Path): Bool
|
|
65
|
-
target node async """
|
|
66
|
-
import * as path from 'path'
|
|
67
|
-
if(path_ === '/') return true
|
|
68
|
-
const childPath = path.resolve(self_)
|
|
69
|
-
const parentPath = path.resolve(path_)
|
|
70
|
-
return childPath.startsWith(parentPath + path.sep) || childPath === parentPath
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
size(): Int
|
|
74
|
-
target node async """
|
|
75
|
-
return (await fs.promises.stat(file)).size
|
|
76
|
-
"""
|
|
77
|
-
|
|
78
|
-
modified(): Instant
|
|
79
|
-
target node async """
|
|
80
|
-
return (await fs.promises.stat(file)).mtimeMs * 0.001
|
|
81
|
-
"""
|
|
82
|
-
|
|
83
|
-
entries(): Stream[PathEntry]
|
|
84
|
-
target node async """
|
|
85
|
-
import * as fsPromises from 'fs/promises'
|
|
86
|
-
let dir = null
|
|
87
|
-
return ff_core_Stream.Stream(
|
|
88
|
-
async () => {
|
|
89
|
-
if(dir === null) dir = await fsPromises.opendir(self_, {bufferSize: 128})
|
|
90
|
-
const entry = await dir.read()
|
|
91
|
-
if(entry === null) return ff_core_Option.None()
|
|
92
|
-
entry.ffPath = self_
|
|
93
|
-
return ff_core_Option.Some(entry)
|
|
94
|
-
},
|
|
95
|
-
async () => {
|
|
96
|
-
if(dir !== null) await dir.close()
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
"""
|
|
100
|
-
|
|
101
|
-
absolute(): String
|
|
102
|
-
target node async """
|
|
103
|
-
import * as path from 'path'
|
|
104
|
-
return path.resolve(self_)
|
|
105
|
-
"""
|
|
106
|
-
|
|
107
|
-
relativeTo(path: Path): String
|
|
108
|
-
target node async """
|
|
109
|
-
import * as path from 'path';
|
|
110
|
-
return path.relative(path_, self_);
|
|
111
|
-
"""
|
|
112
|
-
|
|
113
|
-
endsWith(parts: List[String]): Bool {
|
|
114
|
-
function go(pathOption: Option[Path], reversed: List[String]): Bool {
|
|
115
|
-
| _, [] => True
|
|
116
|
-
| Some(path), [p, ...ps] => path.base() == p && go(path.parent(), ps)
|
|
117
|
-
| None, _ => False
|
|
118
|
-
}
|
|
119
|
-
go(Some(self), parts.reverse())
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
contains(parts: List[String]): Bool {
|
|
123
|
-
self.endsWith(parts) || self.parent().any {_.contains(parts)}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
base(): String
|
|
127
|
-
target node async """
|
|
128
|
-
import * as path from 'path'
|
|
129
|
-
return path.basename(self_)
|
|
130
|
-
"""
|
|
131
|
-
|
|
132
|
-
extension(): String
|
|
133
|
-
target node async """
|
|
134
|
-
import * as path from 'path'
|
|
135
|
-
return path.extname(self_)
|
|
136
|
-
"""
|
|
137
|
-
|
|
138
|
-
url(): String
|
|
139
|
-
target node async """
|
|
140
|
-
import * as url from 'url';
|
|
141
|
-
return '' + url.pathToFileURL(self_);
|
|
142
|
-
"""
|
|
143
|
-
|
|
144
|
-
delimiter(): String
|
|
145
|
-
target node async """
|
|
146
|
-
import * as path from 'path';
|
|
147
|
-
return path.delimiter(self_);
|
|
148
|
-
"""
|
|
149
|
-
|
|
150
|
-
separator(): String
|
|
151
|
-
target node async """
|
|
152
|
-
import * as path from 'path';
|
|
153
|
-
return path.separator();
|
|
154
|
-
"""
|
|
155
|
-
|
|
156
|
-
parent(): Option[Path]
|
|
157
|
-
target node async """
|
|
158
|
-
import * as path from 'path'
|
|
159
|
-
const result = path.dirname(self_)
|
|
160
|
-
return result !== "" && result !== self_
|
|
161
|
-
? ff_core_Option.Some(result)
|
|
162
|
-
: ff_core_Option.None()
|
|
163
|
-
"""
|
|
164
|
-
|
|
165
|
-
slash(relativePath: String): Path
|
|
166
|
-
target node async """
|
|
167
|
-
import * as path from 'path'
|
|
168
|
-
return path.join(self_, relativePath_)
|
|
169
|
-
"""
|
|
170
|
-
|
|
171
|
-
path(absoluteOrRelativePath: String): Path
|
|
172
|
-
target node async """
|
|
173
|
-
import * as path from 'path'
|
|
174
|
-
return path.resolve(self_, absoluteOrRelativePath_)
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
copyTo(path: Path, retries: Int = 0, retryDelay: Int = 100) {
|
|
178
|
-
if(self.isDirectory()) {
|
|
179
|
-
if(path.exists()) {path.delete(retries, retryDelay)}
|
|
180
|
-
path.createDirectory()
|
|
181
|
-
self.entries().each {file =>
|
|
182
|
-
file.path().copyTo(path.slash(file.path().relativeTo(self)), retries, retryDelay)
|
|
183
|
-
}
|
|
184
|
-
} else {
|
|
185
|
-
path.writeStream(self.readStream())
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
createDirectory(createParentDirectories: Bool = False)
|
|
190
|
-
target node async """
|
|
191
|
-
import * as fsPromises from 'fs/promises'
|
|
192
|
-
await fsPromises.mkdir(self_, {recursive: createParentDirectories_})
|
|
193
|
-
"""
|
|
194
|
-
|
|
195
|
-
createSymlinkTo(path: Path)
|
|
196
|
-
target node async """
|
|
197
|
-
import * as fsPromises from 'fs/promises'
|
|
198
|
-
await fsPromises.symlink(path_, self_)
|
|
199
|
-
"""
|
|
200
|
-
|
|
201
|
-
delete(retries: Int = 0, retryDelay: Int = 100)
|
|
202
|
-
target node async """
|
|
203
|
-
import * as fsPromises from 'fs/promises'
|
|
204
|
-
await fsPromises.rm(self_, {recursive: true, retries: retries_, retryDelay: retryDelay_})
|
|
205
|
-
"""
|
|
206
|
-
|
|
207
|
-
truncate(length: Int = 0)
|
|
208
|
-
target node async """
|
|
209
|
-
import * as fsPromises from 'fs/promises'
|
|
210
|
-
await fsPromises.truncate(self_, length_)
|
|
211
|
-
"""
|
|
212
|
-
|
|
213
|
-
renameTo(path: Path)
|
|
214
|
-
target node async """
|
|
215
|
-
import * as fsPromises from 'fs/promises'
|
|
216
|
-
await fsPromises.rename(self_, path_)
|
|
217
|
-
"""
|
|
218
|
-
|
|
219
|
-
readText(): String
|
|
220
|
-
target node async """
|
|
221
|
-
import * as fsPromises from 'fs/promises'
|
|
222
|
-
try {
|
|
223
|
-
return await fsPromises.readFile(self_, {encoding: 'UTF-8', signal: $task.controller.signal})
|
|
224
|
-
} finally {
|
|
225
|
-
if($task.controller.signal.aborted) $task.controller = new AbortController()
|
|
226
|
-
}
|
|
227
|
-
"""
|
|
228
|
-
|
|
229
|
-
writeText(text: String)
|
|
230
|
-
target node async """
|
|
231
|
-
import * as fsPromises from 'fs/promises'
|
|
232
|
-
try {
|
|
233
|
-
await fsPromises.writeFile(self_, text_, {encoding: 'UTF-8', signal: $task.controller.signal})
|
|
234
|
-
} finally {
|
|
235
|
-
if($task.controller.signal.aborted) $task.controller = new AbortController()
|
|
236
|
-
}
|
|
237
|
-
"""
|
|
238
|
-
|
|
239
|
-
appendText(text: String)
|
|
240
|
-
target node async """
|
|
241
|
-
import * as fsPromises from 'fs/promises'
|
|
242
|
-
try {
|
|
243
|
-
await fsPromises.appendFile(self_, text_, {encoding: 'UTF-8', signal: $task.controller.signal})
|
|
244
|
-
} finally {
|
|
245
|
-
if($task.controller.signal.aborted) $task.controller = new AbortController()
|
|
246
|
-
}
|
|
247
|
-
"""
|
|
248
|
-
|
|
249
|
-
readBuffer(): Buffer {
|
|
250
|
-
self.readStream().toBuffer()
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
writeBuffer(buffer: Buffer) {
|
|
254
|
-
self.writeStream([buffer].toStream())
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
appendBuffer(buffer: Buffer) {
|
|
258
|
-
self.appendStream([buffer].toStream())
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
readStream(): Stream[Buffer]
|
|
262
|
-
target node async """
|
|
263
|
-
import * as fs from 'fs'
|
|
264
|
-
return ff_core_Path.internalReadStream_$(() => fs.createReadStream(self_))
|
|
265
|
-
"""
|
|
266
|
-
|
|
267
|
-
writeStream(stream: Stream[Buffer], createOnly: Bool = False)
|
|
268
|
-
target node async """
|
|
269
|
-
import * as fs from 'fs'
|
|
270
|
-
let writeable = fs.createWriteStream(self_, {flags: createOnly_ ? 'wx' : 'w'})
|
|
271
|
-
try {
|
|
272
|
-
await ff_core_Stream.Stream_each$(stream_, async buffer => {
|
|
273
|
-
if(!writeable.write(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength))) {
|
|
274
|
-
await new Promise((resolve, reject) => {
|
|
275
|
-
$task.controller.signal.addEventListener('abort', reject)
|
|
276
|
-
writeable.once('drain', () => {
|
|
277
|
-
$task.controller.signal.removeEventListener('abort', reject)
|
|
278
|
-
resolve()
|
|
279
|
-
})
|
|
280
|
-
})
|
|
281
|
-
}
|
|
282
|
-
}, $task)
|
|
283
|
-
} finally {
|
|
284
|
-
await new Promise((resolve, reject) => {
|
|
285
|
-
writeable.close(err => {if(err) reject(err); else resolve();});
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
"""
|
|
289
|
-
|
|
290
|
-
appendStream(stream: Stream[Buffer])
|
|
291
|
-
target node async """
|
|
292
|
-
import * as fs from 'fs'
|
|
293
|
-
let writeable = fs.createWriteStream(self_, {flags: 'a'})
|
|
294
|
-
try {
|
|
295
|
-
await ff_core_Stream.Stream_each$(stream_, async buffer => {
|
|
296
|
-
if(!writeable.write(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength))) {
|
|
297
|
-
await new Promise((resolve, reject) => {
|
|
298
|
-
$task.controller.signal.addEventListener('abort', reject)
|
|
299
|
-
writeable.once('drain', () => {
|
|
300
|
-
$task.controller.signal.removeEventListener('abort', reject)
|
|
301
|
-
resolve()
|
|
302
|
-
})
|
|
303
|
-
})
|
|
304
|
-
}
|
|
305
|
-
}, $task)
|
|
306
|
-
} finally {
|
|
307
|
-
await new Promise((resolve, reject) => {
|
|
308
|
-
writeable.close(err => {if(err) reject(err); else resolve();});
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
"""
|
|
312
|
-
|
|
313
|
-
readHandle(alsoWrite: Bool = False): FileHandle
|
|
314
|
-
target node async """
|
|
315
|
-
import * as fsPromises from 'fs/promises'
|
|
316
|
-
return await fsPromises.open(self_, alsoWrite_ ? 'r+' : 'r')
|
|
317
|
-
"""
|
|
318
|
-
|
|
319
|
-
writeHandle(alsoRead: Bool = False, mustCreate: Bool = False): FileHandle
|
|
320
|
-
target node async """
|
|
321
|
-
import * as fsPromises from 'fs/promises'
|
|
322
|
-
return await fsPromises.open(self_, (mustCreate_ ? 'wx' : 'w') + (alsoRead_ ? '+' : ''))
|
|
323
|
-
"""
|
|
324
|
-
|
|
325
|
-
appendHandle(alsoRead: Bool = False, mustCreate: Bool = False): FileHandle
|
|
326
|
-
target node async """
|
|
327
|
-
import * as fsPromises from 'fs/promises'
|
|
328
|
-
return await fsPromises.open(self_, (mustCreate_ ? 'wx' : 'w') + (alsoRead_ ? '+' : ''))
|
|
329
|
-
"""
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
extend self: PathEntry {
|
|
334
|
-
|
|
335
|
-
path(): Path
|
|
336
|
-
target node async """
|
|
337
|
-
import * as path from 'path'
|
|
338
|
-
return path.join(self_.ffPath, self_.name)
|
|
339
|
-
"""
|
|
340
|
-
|
|
341
|
-
isDirectory(): Bool
|
|
342
|
-
target node async """
|
|
343
|
-
return self_.isDirectory()
|
|
344
|
-
"""
|
|
345
|
-
|
|
346
|
-
isFile(): Bool
|
|
347
|
-
target node async """
|
|
348
|
-
return self_.isFile()
|
|
349
|
-
"""
|
|
350
|
-
|
|
351
|
-
isSymbolicLink(): Bool
|
|
352
|
-
target node async """
|
|
353
|
-
return self_.isSymbolicLink()
|
|
354
|
-
"""
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
internalReadStream(createReadStream: () => JsValue): Stream[Buffer]
|
|
359
|
-
target node async """
|
|
360
|
-
let task = null
|
|
361
|
-
let readable = null
|
|
362
|
-
let doResolve = null
|
|
363
|
-
let doReject = null
|
|
364
|
-
let seenError = null
|
|
365
|
-
const abort = () => {
|
|
366
|
-
if(task != null) {
|
|
367
|
-
task.controller.signal.removeEventListener('abort', abort)
|
|
368
|
-
readable.destroy()
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
function open($task) {
|
|
372
|
-
ff_core_Task.Task_throwIfAborted($task)
|
|
373
|
-
task = $task
|
|
374
|
-
readable = createReadStream_()
|
|
375
|
-
readable.on('readable', () => {
|
|
376
|
-
if(doResolve != null) doResolve()
|
|
377
|
-
})
|
|
378
|
-
readable.on('error', error => {
|
|
379
|
-
task.controller.signal.removeEventListener('abort', abort)
|
|
380
|
-
seenError = error
|
|
381
|
-
if(doReject != null) doReject(error)
|
|
382
|
-
})
|
|
383
|
-
readable.on('close', () => {
|
|
384
|
-
task.controller.signal.removeEventListener('abort', abort)
|
|
385
|
-
if(doResolve != null) doResolve()
|
|
386
|
-
})
|
|
387
|
-
$task.controller.signal.addEventListener('abort', abort)
|
|
388
|
-
}
|
|
389
|
-
return ff_core_Stream.Stream(async function go($task) {
|
|
390
|
-
if(task == null) open($task)
|
|
391
|
-
let buffer = readable.read()
|
|
392
|
-
if(buffer != null) return ff_core_Option.Some(new DataView(buffer.buffer, buffer.byteOffset, buffer.length))
|
|
393
|
-
if(seenError != null) throw seenError
|
|
394
|
-
if(readable.destroyed) return ff_core_Option.None()
|
|
395
|
-
let promise = new Promise((resolve, reject) => {
|
|
396
|
-
doResolve = () => {doResolve = null; doReject = null; resolve()}
|
|
397
|
-
doReject = error => {doResolve = null; doReject = null; reject(error)}
|
|
398
|
-
}).then(() => go($task))
|
|
399
|
-
return await promise
|
|
400
|
-
}, abort)
|
|
401
|
-
"""
|
|
1
|
+
capability Path {}
|
|
2
|
+
capability PathEntry {}
|
|
3
|
+
|
|
4
|
+
extend self: Path {
|
|
5
|
+
|
|
6
|
+
exists(checkReadable: Bool = False, checkWritable: Bool = False, checkExecutable: Bool = False): Bool
|
|
7
|
+
target node async """
|
|
8
|
+
import * as fs from 'fs'
|
|
9
|
+
import * as fsPromises from 'fs/promises'
|
|
10
|
+
const flags =
|
|
11
|
+
(fs.constants.R_OK * checkReadable_) |
|
|
12
|
+
(fs.constants.W_OK * checkWritable_) |
|
|
13
|
+
(fs.constants.X_OK * checkExecutable_)
|
|
14
|
+
try {
|
|
15
|
+
await fsPromises.access(self_, flags === 0 ? fs.constants.F_OK : flags)
|
|
16
|
+
return true
|
|
17
|
+
} catch(e) {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
isReadable(): Bool {
|
|
23
|
+
self.exists(checkReadable = True)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
isWritable(): Bool {
|
|
27
|
+
self.exists(checkWritable = True)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
isExecutable(): Bool {
|
|
31
|
+
self.exists(checkExecutable = True)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
isDirectory(): Bool
|
|
35
|
+
target node async """
|
|
36
|
+
import * as fsPromises from 'fs/promises'
|
|
37
|
+
try {
|
|
38
|
+
return (await fsPromises.lstat(self_)).isDirectory();
|
|
39
|
+
} catch(e) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
isFile(): Bool
|
|
45
|
+
target node async """
|
|
46
|
+
import * as fsPromises from 'fs/promises'
|
|
47
|
+
try {
|
|
48
|
+
return (await fsPromises.lstat(self_)).isFile();
|
|
49
|
+
} catch(e) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
isSymbolicLink(): Bool
|
|
55
|
+
target node async """
|
|
56
|
+
import * as fsPromises from 'fs/promises'
|
|
57
|
+
try {
|
|
58
|
+
return (await fsPromises.lstat(self_)).isSymbolicLink();
|
|
59
|
+
} catch(e) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
isInsideOf(path: Path): Bool
|
|
65
|
+
target node async """
|
|
66
|
+
import * as path from 'path'
|
|
67
|
+
if(path_ === '/') return true
|
|
68
|
+
const childPath = path.resolve(self_)
|
|
69
|
+
const parentPath = path.resolve(path_)
|
|
70
|
+
return childPath.startsWith(parentPath + path.sep) || childPath === parentPath
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
size(): Int
|
|
74
|
+
target node async """
|
|
75
|
+
return (await fs.promises.stat(file)).size
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
modified(): Instant
|
|
79
|
+
target node async """
|
|
80
|
+
return (await fs.promises.stat(file)).mtimeMs * 0.001
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
entries(): Stream[PathEntry]
|
|
84
|
+
target node async """
|
|
85
|
+
import * as fsPromises from 'fs/promises'
|
|
86
|
+
let dir = null
|
|
87
|
+
return ff_core_Stream.Stream(
|
|
88
|
+
async () => {
|
|
89
|
+
if(dir === null) dir = await fsPromises.opendir(self_, {bufferSize: 128})
|
|
90
|
+
const entry = await dir.read()
|
|
91
|
+
if(entry === null) return ff_core_Option.None()
|
|
92
|
+
entry.ffPath = self_
|
|
93
|
+
return ff_core_Option.Some(entry)
|
|
94
|
+
},
|
|
95
|
+
async () => {
|
|
96
|
+
if(dir !== null) await dir.close()
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
absolute(): String
|
|
102
|
+
target node async """
|
|
103
|
+
import * as path from 'path'
|
|
104
|
+
return path.resolve(self_)
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
relativeTo(path: Path): String
|
|
108
|
+
target node async """
|
|
109
|
+
import * as path from 'path';
|
|
110
|
+
return path.relative(path_, self_);
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
endsWith(parts: List[String]): Bool {
|
|
114
|
+
function go(pathOption: Option[Path], reversed: List[String]): Bool {
|
|
115
|
+
| _, [] => True
|
|
116
|
+
| Some(path), [p, ...ps] => path.base() == p && go(path.parent(), ps)
|
|
117
|
+
| None, _ => False
|
|
118
|
+
}
|
|
119
|
+
go(Some(self), parts.reverse())
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
contains(parts: List[String]): Bool {
|
|
123
|
+
self.endsWith(parts) || self.parent().any {_.contains(parts)}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
base(): String
|
|
127
|
+
target node async """
|
|
128
|
+
import * as path from 'path'
|
|
129
|
+
return path.basename(self_)
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
extension(): String
|
|
133
|
+
target node async """
|
|
134
|
+
import * as path from 'path'
|
|
135
|
+
return path.extname(self_)
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
url(): String
|
|
139
|
+
target node async """
|
|
140
|
+
import * as url from 'url';
|
|
141
|
+
return '' + url.pathToFileURL(self_);
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
delimiter(): String
|
|
145
|
+
target node async """
|
|
146
|
+
import * as path from 'path';
|
|
147
|
+
return path.delimiter(self_);
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
separator(): String
|
|
151
|
+
target node async """
|
|
152
|
+
import * as path from 'path';
|
|
153
|
+
return path.separator();
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
parent(): Option[Path]
|
|
157
|
+
target node async """
|
|
158
|
+
import * as path from 'path'
|
|
159
|
+
const result = path.dirname(self_)
|
|
160
|
+
return result !== "" && result !== self_
|
|
161
|
+
? ff_core_Option.Some(result)
|
|
162
|
+
: ff_core_Option.None()
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
slash(relativePath: String): Path
|
|
166
|
+
target node async """
|
|
167
|
+
import * as path from 'path'
|
|
168
|
+
return path.join(self_, relativePath_)
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
path(absoluteOrRelativePath: String): Path
|
|
172
|
+
target node async """
|
|
173
|
+
import * as path from 'path'
|
|
174
|
+
return path.resolve(self_, absoluteOrRelativePath_)
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
copyTo(path: Path, retries: Int = 0, retryDelay: Int = 100) {
|
|
178
|
+
if(self.isDirectory()) {
|
|
179
|
+
if(path.exists()) {path.delete(retries, retryDelay)}
|
|
180
|
+
path.createDirectory()
|
|
181
|
+
self.entries().each {file =>
|
|
182
|
+
file.path().copyTo(path.slash(file.path().relativeTo(self)), retries, retryDelay)
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
path.writeStream(self.readStream())
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
createDirectory(createParentDirectories: Bool = False)
|
|
190
|
+
target node async """
|
|
191
|
+
import * as fsPromises from 'fs/promises'
|
|
192
|
+
await fsPromises.mkdir(self_, {recursive: createParentDirectories_})
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
createSymlinkTo(path: Path)
|
|
196
|
+
target node async """
|
|
197
|
+
import * as fsPromises from 'fs/promises'
|
|
198
|
+
await fsPromises.symlink(path_, self_)
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
delete(retries: Int = 0, retryDelay: Int = 100)
|
|
202
|
+
target node async """
|
|
203
|
+
import * as fsPromises from 'fs/promises'
|
|
204
|
+
await fsPromises.rm(self_, {recursive: true, retries: retries_, retryDelay: retryDelay_})
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
truncate(length: Int = 0)
|
|
208
|
+
target node async """
|
|
209
|
+
import * as fsPromises from 'fs/promises'
|
|
210
|
+
await fsPromises.truncate(self_, length_)
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
renameTo(path: Path)
|
|
214
|
+
target node async """
|
|
215
|
+
import * as fsPromises from 'fs/promises'
|
|
216
|
+
await fsPromises.rename(self_, path_)
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
readText(): String
|
|
220
|
+
target node async """
|
|
221
|
+
import * as fsPromises from 'fs/promises'
|
|
222
|
+
try {
|
|
223
|
+
return await fsPromises.readFile(self_, {encoding: 'UTF-8', signal: $task.controller.signal})
|
|
224
|
+
} finally {
|
|
225
|
+
if($task.controller.signal.aborted) $task.controller = new AbortController()
|
|
226
|
+
}
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
writeText(text: String)
|
|
230
|
+
target node async """
|
|
231
|
+
import * as fsPromises from 'fs/promises'
|
|
232
|
+
try {
|
|
233
|
+
await fsPromises.writeFile(self_, text_, {encoding: 'UTF-8', signal: $task.controller.signal})
|
|
234
|
+
} finally {
|
|
235
|
+
if($task.controller.signal.aborted) $task.controller = new AbortController()
|
|
236
|
+
}
|
|
237
|
+
"""
|
|
238
|
+
|
|
239
|
+
appendText(text: String)
|
|
240
|
+
target node async """
|
|
241
|
+
import * as fsPromises from 'fs/promises'
|
|
242
|
+
try {
|
|
243
|
+
await fsPromises.appendFile(self_, text_, {encoding: 'UTF-8', signal: $task.controller.signal})
|
|
244
|
+
} finally {
|
|
245
|
+
if($task.controller.signal.aborted) $task.controller = new AbortController()
|
|
246
|
+
}
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
readBuffer(): Buffer {
|
|
250
|
+
self.readStream().toBuffer()
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
writeBuffer(buffer: Buffer) {
|
|
254
|
+
self.writeStream([buffer].toStream())
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
appendBuffer(buffer: Buffer) {
|
|
258
|
+
self.appendStream([buffer].toStream())
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
readStream(): Stream[Buffer]
|
|
262
|
+
target node async """
|
|
263
|
+
import * as fs from 'fs'
|
|
264
|
+
return ff_core_Path.internalReadStream_$(() => fs.createReadStream(self_))
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
writeStream(stream: Stream[Buffer], createOnly: Bool = False)
|
|
268
|
+
target node async """
|
|
269
|
+
import * as fs from 'fs'
|
|
270
|
+
let writeable = fs.createWriteStream(self_, {flags: createOnly_ ? 'wx' : 'w'})
|
|
271
|
+
try {
|
|
272
|
+
await ff_core_Stream.Stream_each$(stream_, async buffer => {
|
|
273
|
+
if(!writeable.write(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength))) {
|
|
274
|
+
await new Promise((resolve, reject) => {
|
|
275
|
+
$task.controller.signal.addEventListener('abort', reject)
|
|
276
|
+
writeable.once('drain', () => {
|
|
277
|
+
$task.controller.signal.removeEventListener('abort', reject)
|
|
278
|
+
resolve()
|
|
279
|
+
})
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
}, $task)
|
|
283
|
+
} finally {
|
|
284
|
+
await new Promise((resolve, reject) => {
|
|
285
|
+
writeable.close(err => {if(err) reject(err); else resolve();});
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
appendStream(stream: Stream[Buffer])
|
|
291
|
+
target node async """
|
|
292
|
+
import * as fs from 'fs'
|
|
293
|
+
let writeable = fs.createWriteStream(self_, {flags: 'a'})
|
|
294
|
+
try {
|
|
295
|
+
await ff_core_Stream.Stream_each$(stream_, async buffer => {
|
|
296
|
+
if(!writeable.write(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength))) {
|
|
297
|
+
await new Promise((resolve, reject) => {
|
|
298
|
+
$task.controller.signal.addEventListener('abort', reject)
|
|
299
|
+
writeable.once('drain', () => {
|
|
300
|
+
$task.controller.signal.removeEventListener('abort', reject)
|
|
301
|
+
resolve()
|
|
302
|
+
})
|
|
303
|
+
})
|
|
304
|
+
}
|
|
305
|
+
}, $task)
|
|
306
|
+
} finally {
|
|
307
|
+
await new Promise((resolve, reject) => {
|
|
308
|
+
writeable.close(err => {if(err) reject(err); else resolve();});
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
"""
|
|
312
|
+
|
|
313
|
+
readHandle(alsoWrite: Bool = False): FileHandle
|
|
314
|
+
target node async """
|
|
315
|
+
import * as fsPromises from 'fs/promises'
|
|
316
|
+
return await fsPromises.open(self_, alsoWrite_ ? 'r+' : 'r')
|
|
317
|
+
"""
|
|
318
|
+
|
|
319
|
+
writeHandle(alsoRead: Bool = False, mustCreate: Bool = False): FileHandle
|
|
320
|
+
target node async """
|
|
321
|
+
import * as fsPromises from 'fs/promises'
|
|
322
|
+
return await fsPromises.open(self_, (mustCreate_ ? 'wx' : 'w') + (alsoRead_ ? '+' : ''))
|
|
323
|
+
"""
|
|
324
|
+
|
|
325
|
+
appendHandle(alsoRead: Bool = False, mustCreate: Bool = False): FileHandle
|
|
326
|
+
target node async """
|
|
327
|
+
import * as fsPromises from 'fs/promises'
|
|
328
|
+
return await fsPromises.open(self_, (mustCreate_ ? 'wx' : 'w') + (alsoRead_ ? '+' : ''))
|
|
329
|
+
"""
|
|
330
|
+
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
extend self: PathEntry {
|
|
334
|
+
|
|
335
|
+
path(): Path
|
|
336
|
+
target node async """
|
|
337
|
+
import * as path from 'path'
|
|
338
|
+
return path.join(self_.ffPath, self_.name)
|
|
339
|
+
"""
|
|
340
|
+
|
|
341
|
+
isDirectory(): Bool
|
|
342
|
+
target node async """
|
|
343
|
+
return self_.isDirectory()
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
isFile(): Bool
|
|
347
|
+
target node async """
|
|
348
|
+
return self_.isFile()
|
|
349
|
+
"""
|
|
350
|
+
|
|
351
|
+
isSymbolicLink(): Bool
|
|
352
|
+
target node async """
|
|
353
|
+
return self_.isSymbolicLink()
|
|
354
|
+
"""
|
|
355
|
+
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
internalReadStream(createReadStream: () => JsValue): Stream[Buffer]
|
|
359
|
+
target node async """
|
|
360
|
+
let task = null
|
|
361
|
+
let readable = null
|
|
362
|
+
let doResolve = null
|
|
363
|
+
let doReject = null
|
|
364
|
+
let seenError = null
|
|
365
|
+
const abort = () => {
|
|
366
|
+
if(task != null) {
|
|
367
|
+
task.controller.signal.removeEventListener('abort', abort)
|
|
368
|
+
readable.destroy()
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function open($task) {
|
|
372
|
+
ff_core_Task.Task_throwIfAborted($task)
|
|
373
|
+
task = $task
|
|
374
|
+
readable = createReadStream_()
|
|
375
|
+
readable.on('readable', () => {
|
|
376
|
+
if(doResolve != null) doResolve()
|
|
377
|
+
})
|
|
378
|
+
readable.on('error', error => {
|
|
379
|
+
task.controller.signal.removeEventListener('abort', abort)
|
|
380
|
+
seenError = error
|
|
381
|
+
if(doReject != null) doReject(error)
|
|
382
|
+
})
|
|
383
|
+
readable.on('close', () => {
|
|
384
|
+
task.controller.signal.removeEventListener('abort', abort)
|
|
385
|
+
if(doResolve != null) doResolve()
|
|
386
|
+
})
|
|
387
|
+
$task.controller.signal.addEventListener('abort', abort)
|
|
388
|
+
}
|
|
389
|
+
return ff_core_Stream.Stream(async function go($task) {
|
|
390
|
+
if(task == null) open($task)
|
|
391
|
+
let buffer = readable.read()
|
|
392
|
+
if(buffer != null) return ff_core_Option.Some(new DataView(buffer.buffer, buffer.byteOffset, buffer.length))
|
|
393
|
+
if(seenError != null) throw seenError
|
|
394
|
+
if(readable.destroyed) return ff_core_Option.None()
|
|
395
|
+
let promise = new Promise((resolve, reject) => {
|
|
396
|
+
doResolve = () => {doResolve = null; doReject = null; resolve()}
|
|
397
|
+
doReject = error => {doResolve = null; doReject = null; reject(error)}
|
|
398
|
+
}).then(() => go($task))
|
|
399
|
+
return await promise
|
|
400
|
+
}, abort)
|
|
401
|
+
"""
|