@nxtedition/lib 22.0.6 → 22.0.8
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/ass.js +27 -6
- package/http.js +2 -2
- package/package.json +2 -1
- package/serializers.js +4 -4
- package/util/template/javascript.js +53 -43
- package/util/template/transform.js +22 -0
- package/util/template/transform.test.js +12 -0
package/ass.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import fp from 'lodash/fp.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const BASE_WIDTH = 1920
|
|
4
|
+
const BASE_HEIGHT = 1080
|
|
5
|
+
|
|
6
|
+
export function encodeASS(events, { styles = {}, width = BASE_WIDTH, height = BASE_HEIGHT } = {}) {
|
|
7
|
+
return [
|
|
8
|
+
encASSHeader({ width, height }),
|
|
9
|
+
encASSStyles({ styles, width, height }),
|
|
10
|
+
encASSEvents(events),
|
|
11
|
+
].join('\n')
|
|
5
12
|
}
|
|
6
13
|
|
|
7
14
|
function formatDialogues(events) {
|
|
@@ -80,10 +87,24 @@ const formatStyles = fp.pipe(
|
|
|
80
87
|
}, ''),
|
|
81
88
|
)
|
|
82
89
|
|
|
83
|
-
function encASSStyles(styles) {
|
|
90
|
+
function encASSStyles({ styles, width, height }) {
|
|
91
|
+
const scaledStyles = {}
|
|
92
|
+
|
|
93
|
+
for (const [id, style] of Object.entries(styles)) {
|
|
94
|
+
scaledStyles[id] = { ...style }
|
|
95
|
+
for (const key of ['fontsize', 'marginV', 'marginL', 'marginR']) {
|
|
96
|
+
const scale = key === 'fontsize' ? height / BASE_HEIGHT : width / BASE_WIDTH
|
|
97
|
+
|
|
98
|
+
if (typeof style[key] === 'string') {
|
|
99
|
+
const scaled = Number(style[key]) * scale
|
|
100
|
+
scaledStyles[id][key] = String(Math.round(scaled * 10) / 10)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
84
105
|
return `[V4+ Styles]
|
|
85
106
|
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
|
|
86
|
-
${formatStyles(
|
|
107
|
+
${formatStyles(scaledStyles)}`
|
|
87
108
|
}
|
|
88
109
|
|
|
89
110
|
function encASSHeader({ width, height }) {
|
|
@@ -94,8 +115,8 @@ function encASSHeader({ width, height }) {
|
|
|
94
115
|
// 3: same as 0, but lower line gets wider.
|
|
95
116
|
return `[Script Info]
|
|
96
117
|
ScriptType: v4.00+
|
|
97
|
-
PlayResX: ${width ||
|
|
98
|
-
PlayResY: ${height ||
|
|
118
|
+
PlayResX: ${width || BASE_WIDTH}
|
|
119
|
+
PlayResY: ${height || BASE_HEIGHT}
|
|
99
120
|
WrapStyle: 1
|
|
100
121
|
`
|
|
101
122
|
}
|
package/http.js
CHANGED
|
@@ -102,7 +102,7 @@ export class Context {
|
|
|
102
102
|
set logger(val) {
|
|
103
103
|
this.#logger = val
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
get req() {
|
|
107
107
|
return this.#req
|
|
108
108
|
}
|
|
@@ -134,7 +134,7 @@ export async function requestMiddleware(ctx, next) {
|
|
|
134
134
|
|
|
135
135
|
pendingSet.add(ctx)
|
|
136
136
|
try {
|
|
137
|
-
if (req.method === 'GET' || req.method === 'HEAD') {
|
|
137
|
+
if (req.method === 'GET' || req.method === 'HEAD' || req.method === 'OPTIONS') {
|
|
138
138
|
req.resume() // Dump the body if there is one.
|
|
139
139
|
}
|
|
140
140
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/lib",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Robert Nagy <robert.nagy@boffins.se>",
|
|
6
6
|
"type": "module",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"@elastic/elasticsearch": "^8.16.1",
|
|
59
59
|
"@elastic/transport": "^8.9.1",
|
|
60
60
|
"@nxtedition/nxt-undici": "^4.2.26",
|
|
61
|
+
"@swc/wasm-web": "^1.9.2",
|
|
61
62
|
"content-type": "^1.0.5",
|
|
62
63
|
"date-fns": "^3.6.0",
|
|
63
64
|
"fast-querystring": "^1.1.1",
|
package/serializers.js
CHANGED
|
@@ -98,8 +98,8 @@ export default {
|
|
|
98
98
|
bytesRead: ures.bytesRead,
|
|
99
99
|
bytesReadPerSecond:
|
|
100
100
|
ures.bytesReadPerSecond ??
|
|
101
|
-
(ures.timing
|
|
102
|
-
? (ures.bytesRead * 1e3) / ures.timing.
|
|
101
|
+
(ures.timing && ures.timing.data > 0 && ures.timing.end > 0
|
|
102
|
+
? (ures.bytesRead * 1e3) / (ures.timing.end - ures.timing.data)
|
|
103
103
|
: undefined),
|
|
104
104
|
body: typeof ures.body === 'string' ? ures.body : undefined,
|
|
105
105
|
headers: getHeaders(ures),
|
|
@@ -131,8 +131,8 @@ export default {
|
|
|
131
131
|
bytesWritten: ureq.bytesWritten,
|
|
132
132
|
bytesReadPerSecond:
|
|
133
133
|
ureq.bytesWrittenPerSecond ??
|
|
134
|
-
(ureq.timing
|
|
135
|
-
? (ureq.bytesWritten * 1e3) / ureq.timing.
|
|
134
|
+
(ureq.timing && ureq.timing.data > 0 && ureq.timing.end > 0
|
|
135
|
+
? (ureq.bytesWritten * 1e3) / (ureq.timing.end - ureq.timing.data)
|
|
136
136
|
: undefined),
|
|
137
137
|
headers: getHeaders(ureq),
|
|
138
138
|
query: ureq.query,
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
2
|
import { makeWeakCache } from '../../weakCache.js'
|
|
3
3
|
import * as rxjs from 'rxjs'
|
|
4
|
-
import vm from 'node:vm'
|
|
5
4
|
import objectHash from 'object-hash'
|
|
6
5
|
import * as datefns from 'date-fns'
|
|
7
6
|
import JSON5 from 'json5'
|
|
8
7
|
import { request } from '@nxtedition/nxt-undici'
|
|
9
8
|
import undici from 'undici'
|
|
10
9
|
import fp from 'lodash/fp.js'
|
|
11
|
-
import _ from 'lodash'
|
|
12
10
|
import moment from 'moment-timezone'
|
|
13
11
|
import Timecode from 'smpte-timecode'
|
|
12
|
+
import transform from './transform.js'
|
|
14
13
|
|
|
15
14
|
const SEP = String.fromCharCode(30) // ASCII 1E
|
|
16
15
|
|
|
@@ -190,28 +189,6 @@ class PromiseEntry {
|
|
|
190
189
|
}
|
|
191
190
|
}
|
|
192
191
|
|
|
193
|
-
function pipe(value, ...fns) {
|
|
194
|
-
for (const fn of fns) {
|
|
195
|
-
value = fn(value)
|
|
196
|
-
if (value == null) {
|
|
197
|
-
return value
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return value
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const globals = {
|
|
204
|
-
fp,
|
|
205
|
-
_,
|
|
206
|
-
moment,
|
|
207
|
-
Timecode,
|
|
208
|
-
datefns,
|
|
209
|
-
JSON5,
|
|
210
|
-
pipe,
|
|
211
|
-
$: null,
|
|
212
|
-
nxt: null,
|
|
213
|
-
}
|
|
214
|
-
|
|
215
192
|
function proxify(value, expression, handler, suspend = true) {
|
|
216
193
|
assert(expression)
|
|
217
194
|
assert(handler)
|
|
@@ -238,8 +215,7 @@ function makeWrapper(expression) {
|
|
|
238
215
|
|
|
239
216
|
export default function ({ ds, proxify, compiler }) {
|
|
240
217
|
class Expression {
|
|
241
|
-
constructor(
|
|
242
|
-
this._context = context
|
|
218
|
+
constructor(script, expression, args, observer) {
|
|
243
219
|
this._expression = expression
|
|
244
220
|
this._observer = observer
|
|
245
221
|
this._script = script
|
|
@@ -371,16 +347,48 @@ export default function ({ ds, proxify, compiler }) {
|
|
|
371
347
|
|
|
372
348
|
this._counter = (this._counter + 1) & maxInt
|
|
373
349
|
|
|
374
|
-
// TODO (fix): freeze?
|
|
375
|
-
this._context.$ = this._args
|
|
376
|
-
this._context.nxt = this
|
|
377
|
-
|
|
378
350
|
const previous = compiler.current
|
|
379
351
|
compiler.current = this
|
|
380
352
|
|
|
381
353
|
try {
|
|
382
354
|
assert(this._suspended === false)
|
|
383
|
-
|
|
355
|
+
|
|
356
|
+
const savedThis = {
|
|
357
|
+
fp: globalThis.fp,
|
|
358
|
+
moment: globalThis.moment,
|
|
359
|
+
Timecode: globalThis.Timecode,
|
|
360
|
+
datefns: globalThis.datefns,
|
|
361
|
+
JSON5: globalThis.JSON5,
|
|
362
|
+
$: globalThis.$,
|
|
363
|
+
nxt: globalThis.nxt,
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
let value
|
|
367
|
+
try {
|
|
368
|
+
globalThis.fp = fp
|
|
369
|
+
globalThis.moment = moment
|
|
370
|
+
globalThis.Timecode = Timecode
|
|
371
|
+
globalThis.datefns = datefns
|
|
372
|
+
globalThis.JSON5 = JSON5
|
|
373
|
+
globalThis.$ = this._args
|
|
374
|
+
globalThis.nxt = this
|
|
375
|
+
|
|
376
|
+
// TODO (fix): This should be sandboxed somehow...
|
|
377
|
+
// - Use a webworker?
|
|
378
|
+
// - Use vm for Node only?
|
|
379
|
+
// - Use https://github.com/tc39/proposal-shadowrealm?
|
|
380
|
+
value = this._script()
|
|
381
|
+
} finally {
|
|
382
|
+
globalThis.fp = savedThis.fp
|
|
383
|
+
globalThis._ = savedThis._
|
|
384
|
+
globalThis.moment = savedThis.moment
|
|
385
|
+
globalThis.Timecode = savedThis.Timecode
|
|
386
|
+
globalThis.datefns = savedThis.datefns
|
|
387
|
+
globalThis.JSON5 = savedThis.JSON5
|
|
388
|
+
globalThis.$ = savedThis.$
|
|
389
|
+
globalThis.nxt = savedThis.nxt
|
|
390
|
+
}
|
|
391
|
+
|
|
384
392
|
this._errored = false
|
|
385
393
|
if (this._suspended) {
|
|
386
394
|
return
|
|
@@ -410,9 +418,6 @@ export default function ({ ds, proxify, compiler }) {
|
|
|
410
418
|
} finally {
|
|
411
419
|
compiler.current = previous
|
|
412
420
|
|
|
413
|
-
this._context.$ = null
|
|
414
|
-
this._context.nxt = null
|
|
415
|
-
|
|
416
421
|
this._suspended = false
|
|
417
422
|
this._disposing = true
|
|
418
423
|
|
|
@@ -598,18 +603,25 @@ export default function ({ ds, proxify, compiler }) {
|
|
|
598
603
|
return makeWeakCache((expression) => {
|
|
599
604
|
let script
|
|
600
605
|
try {
|
|
601
|
-
script = new
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
606
|
+
script = new Function(
|
|
607
|
+
transform(`
|
|
608
|
+
const _ = (value, ...fns) => {
|
|
609
|
+
for (const fn of fns) {
|
|
610
|
+
value = fn(value)
|
|
611
|
+
if (value == null) {
|
|
612
|
+
return value
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return value
|
|
616
|
+
};
|
|
605
617
|
_.asset = (type, state, suspend) => (name) => nxt._asset(name, type, state, suspend);
|
|
606
618
|
_.ds = (postfix, state, suspend) => (name) => nxt._ds(name, postfix, state, suspend);
|
|
607
619
|
_.get = (postfix, path, state, suspend) => (name) => nxt._get(name, postfix, path, state, suspend);
|
|
608
620
|
_.timer = (dueTime) => (dueValue) => nxt.timer(dueTime, dueValue);
|
|
609
621
|
_.fetch = (options, suspend) => (resource) => nxt.fetch(resource, options, suspend);
|
|
610
622
|
${expression}
|
|
611
|
-
|
|
612
|
-
|
|
623
|
+
`),
|
|
624
|
+
)
|
|
613
625
|
} catch (err) {
|
|
614
626
|
return () =>
|
|
615
627
|
rxjs.throwError(
|
|
@@ -617,12 +629,10 @@ export default function ({ ds, proxify, compiler }) {
|
|
|
617
629
|
)
|
|
618
630
|
}
|
|
619
631
|
|
|
620
|
-
const context = vm.createContext({ ...globals })
|
|
621
|
-
|
|
622
632
|
return (args) =>
|
|
623
633
|
new rxjs.Observable((o) => {
|
|
624
634
|
try {
|
|
625
|
-
const exp = new Expression(
|
|
635
|
+
const exp = new Expression(script, expression, args, o)
|
|
626
636
|
return () => {
|
|
627
637
|
exp._destroy()
|
|
628
638
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { parseSync, printSync } from '@swc/wasm-web'
|
|
2
|
+
|
|
3
|
+
export default function (code) {
|
|
4
|
+
const ast = parseSync(code, { syntax: 'ecmascript', script: true })
|
|
5
|
+
|
|
6
|
+
const { body } = ast
|
|
7
|
+
|
|
8
|
+
if (body.length > 0) {
|
|
9
|
+
const lastStatement = body[body.length - 1]
|
|
10
|
+
|
|
11
|
+
if (lastStatement.type !== 'ReturnStatement') {
|
|
12
|
+
body[body.length - 1] = {
|
|
13
|
+
type: 'ReturnStatement',
|
|
14
|
+
argument:
|
|
15
|
+
lastStatement.type === 'ExpressionStatement' ? lastStatement.expression : lastStatement,
|
|
16
|
+
span: lastStatement.span,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return printSync(ast).code
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import transform from './transform.js'
|
|
4
|
+
|
|
5
|
+
test('transform', function () {
|
|
6
|
+
assert.strictEqual(transform('const x = 2; x;'), 'const x = 2;\nreturn x;\n')
|
|
7
|
+
assert.strictEqual(transform('[1,2,3];'), 'return [\n 1,\n 2,\n 3\n];\n')
|
|
8
|
+
assert.strictEqual(transform('[1,2,3]'), 'return [\n 1,\n 2,\n 3\n];\n')
|
|
9
|
+
assert.strictEqual(transform('x\n? \n2 \n: \n3'), `return x ? 2 : 3;\n`)
|
|
10
|
+
assert.strictEqual(transform('return x\n? \n2 \n: \n3'), `return x ? 2 : 3;\n`)
|
|
11
|
+
assert.strictEqual(transform('return\n x\n? \n2 \n: \n3'), `return x ? 2 : 3;\n`)
|
|
12
|
+
})
|