Public
Script
Readme

oldstyle

bring back the old @​import.syntax

usage:

import oldstyle from "https://esm.town/v/easrng/oldstyle"; const fn = await oldstyle` export default async () => { // import vals const fetchFns = [@std.fetch, @easrng.moduleFetch]; console.log( await Promise.all( fetchFns.map((fn) => fn("https://icanhazip.com").then((res) => res.text()), ), ), ); // get environment variables with @me.secrets console.log(@me.secrets.FORCE_COLOR); // update vals console.log(@easrng.counter++); }; // you don't have to have an export btw `; fn();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { getMainExport } from "https://esm.town/v/easrng/oldstyleUtil";
// (c) easrng 2024
// SPDX-License-Identifier: CC-BY-NC-SA
type Token =
| { type: "StringLiteral"; value: string; closed: boolean }
| { type: "NoSubstitutionTemplate"; value: string; closed: boolean }
| { type: "TemplateHead"; value: string }
| { type: "TemplateMiddle"; value: string }
| { type: "TemplateTail"; value: string; closed: boolean }
| { type: "RegularExpressionLiteral"; value: string; closed: boolean }
| { type: "MultiLineComment"; value: string; closed: boolean }
| { type: "SingleLineComment"; value: string }
| { type: "HashbangComment"; value: string }
| { type: "IdentifierName"; value: string }
| { type: "PrivateIdentifier"; value: string }
| { type: "ImportIdentifier"; value: string }
| { type: "NumericLiteral"; value: string }
| { type: "Punctuator"; value: string }
| { type: "WhiteSpace"; value: string }
| { type: "LineTerminatorSequence"; value: string }
| { type: "Invalid"; value: string };
type JSXToken =
| { type: "JSXString"; value: string; closed: boolean }
| { type: "JSXText"; value: string }
| { type: "JSXIdentifier"; value: string }
| { type: "JSXPunctuator"; value: string }
| { type: "JSXInvalid"; value: string };
let source = await (await fetch("https://unpkg.com/js-tokens@9.0.0/index.js")).text();
source = source.replace(String.raw`Identifier = /(\x23?)`, String.raw`Identifier = /([@#]?)`);
source = source.replace(
String.raw`match[1] === "#" ? "PrivateIdentifier" : `,
String.raw`match[1] === "#" ? "PrivateIdentifier" : match[1] === "@" ? "ImportIdentifier" : `,
);
source = source.replace("module.exports =", "export default");
const patchedModUrl = URL.createObjectURL(
new Blob([source], {
type: "text/javascript",
}),
);
const { default: tokens } = (await import(patchedModUrl)) as {
default: (
input: string,
options: { jsx: true },
) => Generator<Token | JSXToken, void, void>;
};
URL.revokeObjectURL(patchedModUrl);
export default async function oldstyle(...args: Parameters<typeof String.raw>) {
const gen = tokens(String.raw(...args), { jsx: true });
const identifiers = new Set<string>();
const out: (Token | JSXToken)[] = [];
const importIndices: number[] = [];
for (const token of gen) {
const index = out.push(token) - 1;
if (token.type === "IdentifierName") {
identifiers.add(token.value);
}
if (token.type === "ImportIdentifier") {
importIndices.push(index);
}
}
const identifier = (base: string) => {
for (let i = 0; true; i++) {
const identifier = "$" + (i ? i + "$" : "") + base;
if (!identifiers.has(identifier)) {
identifiers.add(identifier);
return identifier;
}
}
};
const imports = new Map<string, { identifier: string; children: Set<string> }>();
for (const index of importIndices) {
let rawName = out[index].value.slice(1);
let importObj = imports.get(rawName);
if (!importObj) {
imports.set(rawName, importObj = { identifier: identifier(rawName), children: new Set() });
}
out[index] = {
type: "IdentifierName",
value: importObj.identifier,
};
for (let i = index + 1; i < out.length; i++) {
const token = out[i];
if (token.type === "WhiteSpace" || (token.type === "Punctuator" && token.value === ".")) {
continue;
} else if (token.type === "IdentifierName") {
importObj.children.add(token.value);
}
break;
}
}
const getMainExportIdentifier = identifier("getMainExport");
const setIdentifier = identifier("set");
const prefix: string[] = [
`import { getMainExport as ${getMainExportIdentifier}, set as ${setIdentifier} } from "https://esm.town/v/easrng/oldstyleUtil"`,
];
for (const [name, importObj] of imports) {
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
March 6, 2024