Skip to content

Commit

Permalink
New jspm link workflows (#75)
Browse files Browse the repository at this point in the history
* jspm link workflows

* finish up build
  • Loading branch information
guybedford committed Apr 8, 2023
1 parent 1a831fb commit 1356299
Show file tree
Hide file tree
Showing 8 changed files with 344 additions and 296 deletions.
258 changes: 160 additions & 98 deletions docs/cli.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-proposal-decorators": "^7.10.5",
"@babel/plugin-proposal-export-default-from": "^7.10.4",
"@babel/plugin-proposal-export-namespace-from": "^7.10.4",
"@babel/plugin-proposal-numeric-separator": "^7.10.4",
Expand Down
271 changes: 123 additions & 148 deletions src/cli.ts

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class Installer {
resolvedExportsCache = new WeakMap<PackageConfig, Record<string, string>>();

completed = false;
changed = false;

constructor (map: TraceMap, opts: InstallOptions) {
this.traceMap = map;
Expand Down Expand Up @@ -143,6 +144,8 @@ export class Installer {
resolutionMap.pkg = pkg;
else
resolutionMap = this.installs.imports[install.pkgName] = { pkg, exports: Object.create(null) };
// TODO: make change detection actually work
this.changed = true;
return resolutionMap.exports;
}
else {
Expand All @@ -152,6 +155,8 @@ export class Installer {
resolutionMap.pkg = pkg;
else
resolutionMap = scope[install.pkgName] = { pkg, exports: Object.create(null) };
// TODO: make change detection actually work
this.changed = true;
return resolutionMap.exports;
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/installtree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ function createEsmAnalysis (imports: any, source: string, url: string) {
}
}
const size = source.length;
return { deps, dynamicDeps, size, integrity: computeIntegrity(source) };
return { deps, dynamicDeps, size, integrity: computeIntegrity(source), system: false };
}

const registerRegEx = /^\s*(\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*)*\s*System\s*\.\s*register\s*\(\s*(\[[^\]]*\])\s*,\s*\(?function\s*\(\s*([^\),\s]+\s*(,\s*([^\),\s]+)\s*)?\s*)?\)/;
function createSystemAnalysis (source: string, url: string) {
function createSystemAnalysis (source: string, imports: string[], url: string) {
const [, , , rawDeps, , , contextId] = source.match(registerRegEx) || [];
if (!rawDeps)
throw `Source ${url} is not a SystemJS module.`;
return createEsmAnalysis(imports, source, url);
const deps = JSON.parse(rawDeps.replace(/'/g, '"'));
const dynamicDeps: string[] = [];
if (contextId) {
Expand All @@ -164,7 +164,7 @@ function createSystemAnalysis (source: string, url: string) {
}
}
const size = source.length;
return { deps, dynamicDeps, size, integrity: computeIntegrity(source) };
return { deps, dynamicDeps, size, integrity: computeIntegrity(source), system: true };
}

export function getExportsTarget(target, env): string | null {
Expand Down Expand Up @@ -201,7 +201,7 @@ export async function exists (resolvedUrl: string): Promise<boolean> {
}
}

export async function analyze (resolvedUrl: string, parentUrl?: URL, system = false): Promise<{ deps: string[], dynamicDeps: string[], size: number, integrity: string }> {
export async function analyze (resolvedUrl: string, parentUrl?: URL, system = false): Promise<{ deps: string[], dynamicDeps: string[], size: number, integrity: string, system: boolean }> {
const res = await fetch(resolvedUrl);
switch (res.status) {
case 200:
Expand All @@ -213,7 +213,7 @@ export async function analyze (resolvedUrl: string, parentUrl?: URL, system = fa
let source = await res.text();
try {
const [imports] = await lexer.parse(source);
return system ? createSystemAnalysis(source, resolvedUrl) : createEsmAnalysis(imports, source, resolvedUrl);
return system ? createSystemAnalysis(source, imports, resolvedUrl) : createEsmAnalysis(imports, source, resolvedUrl);
}
catch (e) {
if (!e.message || !e.message.startsWith('Parse error @:'))
Expand All @@ -231,7 +231,7 @@ export async function analyze (resolvedUrl: string, parentUrl?: URL, system = fa
source = await res.text();
try {
const [imports] = await lexer.parse(source);
return system ? createSystemAnalysis(source, resolvedUrl) : createEsmAnalysis(imports, source, resolvedUrl);
return system ? createSystemAnalysis(source, imports, resolvedUrl) : createEsmAnalysis(imports, source, resolvedUrl);
}
catch (e) {
// TODO: better parser errors
Expand Down
24 changes: 17 additions & 7 deletions src/rollup-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import babelPluginClassProperties from '@babel/plugin-proposal-class-properties'
import babelPluginNumericSeparator from '@babel/plugin-proposal-numeric-separator';
import pluginProposalExportDefaultFrom from '@babel/plugin-proposal-export-default-from';
import pluginProposalExportNamespaceFrom from '@babel/plugin-proposal-export-namespace-from';
import pluginProposalDecorators from '@babel/plugin-proposal-decorators';

const stage3Syntax = ['asyncGenerators', 'classProperties', 'classPrivateProperties', 'classPrivateMethods', 'dynamicImport', 'importMeta', 'nullishCoalescingOperator', 'numericSeparator', 'optionalCatchBinding', 'optionalChaining', 'objectRestSpread', 'topLevelAwait'];

Expand Down Expand Up @@ -53,17 +54,25 @@ export default ({
if (externals === true && isPlain(specifier)) {
return { id: specifier, external: true };
}
const parentUrl = parent ? (parent[0] !== '/' && isURL(parent) && !parent.match(/^\w:/) ? new URL(parent) : pathToFileURL(parent)) : baseUrl;
let resolved;
try {
resolved = this.traceMap.resolve(specifier, parent ? (parent[0] !== '/' && isURL(parent) && !parent.match(/^\w:/) ? new URL(parent) : pathToFileURL(parent)) : baseUrl);
resolved = this.traceMap.resolve(specifier, parentUrl);
}
catch (e) {
if ((<DecoratedError>e).code === 'MODULE_NOT_FOUND' && isPlain(specifier)) {
console.warn(`\n${chalk.yellow('warn')} Unable to resolve ${chalk.bold(specifier)}, treating as external.`);
return { id: specifier, external: true };
try {
if (parentUrl.origin + '/' !== esmCdnUrl)
throw e;
resolved = this.traceMap.resolve(specifier, new URL(systemCdnUrl + parentUrl.pathname.slice(1)));
}
else {
throw e;
catch (e) {
if ((<DecoratedError>e).code === 'MODULE_NOT_FOUND' && isPlain(specifier)) {
console.warn(`\n${chalk.yellow('warn')} Unable to resolve ${chalk.bold(specifier)}, treating as external.`);
return { id: specifier, external: true };
}
else {
throw e;
}
}
}
if (resolved === null) return '@empty';
Expand Down Expand Up @@ -137,7 +146,8 @@ export default ({
pluginProposalExportDefaultFrom,
pluginProposalExportNamespaceFrom,
babelPluginClassProperties,
babelPluginNumericSeparator
babelPluginNumericSeparator,
[pluginProposalDecorators, { decoratorsBeforeExport: true }],
],
presets: [[babelPresetTypeScript, {
allowDeclareFields: true,
Expand Down
63 changes: 29 additions & 34 deletions src/tracemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@ const Pool = (n = 1) => class PoolClass {
next () { this.c--; this.q.pop() || (() => {}) }
};

interface TraceEntry {
deps: Record<string, URL | null>;
dynamicDeps: Record<string, URL | null>;
dynamicOnly: boolean;
size: number;
order: number;
integrity: string;
system: boolean;
}
export interface Trace {
[url: string]: {
deps: Record<string, URL | null>;
dynamicDeps: Record<string, URL | null>;
dynamicOnly: boolean;
size: number;
order: number;
integrity: string;
};
[url: string]: TraceEntry;
}

export class TraceMap {
Expand Down Expand Up @@ -250,7 +252,8 @@ export class TraceMap {
this._map.integrity = alphabetize(this._map.integrity);
}

async trace (specifiers: string[], system = false, doDepcache = false): Promise<Trace> {
async trace (specifiers: string[], system = false, doDepcache = false): Promise<{ map: Record<string, URL | null>, trace: Trace, allSystem: boolean }> {
let allSystem = true;
let postOrder = 0;
let dynamicTracing = false;
const dynamics: Set<{ dep: string, parentUrl: URL }> = new Set();
Expand All @@ -274,17 +277,21 @@ export class TraceMap {
this._map.depcache[parent] = [specifier];
}
}
const curEntry = curTrace[href] = {
const curEntry: TraceEntry = curTrace[href] = {
deps: Object.create(null),
dynamicDeps: Object.create(null),
dynamicOnly: dynamicTracing,
size: NaN,
order: NaN,
integrity: ''
integrity: '',
system: false,
};
const { deps, dynamicDeps, size, integrity } = await analyze(href, parentUrl, system);
const { deps, dynamicDeps, size, integrity, system: isSystem } = await analyze(href, parentUrl, system);
curEntry.integrity = integrity;
curEntry.size = size;
curEntry.system = isSystem;
if (!isSystem)
allSystem = false;

for (const dep of deps)
await doTrace(dep, resolved, curTrace, curEntry.deps, false);
Expand Down Expand Up @@ -314,50 +321,37 @@ export class TraceMap {
}
}

return { map, trace: staticTrace };
return { map, trace: staticTrace, allSystem };
}

// modules are resolvable module specifiers
// exception is package-like, which we should probably not allow for this top-level version
async traceInstall (modules?: string | string[] | InstallOptions, opts: InstallOptions = {}) {
async traceInstall (modules?: string | string[] | InstallOptions, opts: InstallOptions = {}): Promise<boolean> {
if (typeof modules === 'string') modules = [modules];
if (!Array.isArray(modules)) {
opts = { lock: true, ...modules || {} };
modules = Object.keys(this._map.imports);
}
await this._p.job();
try {
const installer = new Installer(this, opts);
await Promise.all(modules.map(module => installer.traceInstall(module, this._baseUrl, false)));
installer.complete();
}
finally {
this._p.next();
}
return this;
}

async install (opts: InstallOptions = {}, imports?: string[]) {
opts.lock = true;
await this._p.job();
if (opts.clean !== false)
opts.clean = true;
await this._p.job();
let installed = false;
try {
const installer = new Installer(this, opts);
for (const specifier of imports || Object.keys(this._map.imports)) {
await installer.traceInstall(specifier, this._baseUrl, false);
}
await Promise.all(modules.map(module => installer.traceInstall(module, this._baseUrl, false)));
installer.complete();
installed = installer.changed;
}
finally {
this._p.next();
}
return this;
return installed;
}

async add (packages: string | (string | { name: string, target: string })[], opts: InstallOptions = {}) {
if (typeof packages === 'string') packages = [packages];
await this._p.job();
let changed = false;
try {
const installer = new Installer(this, opts);
await Promise.all(packages.map(pkg => {
Expand All @@ -375,11 +369,12 @@ export class TraceMap {
return installer.add(pkg.target, pkg.name);
}));
installer.complete();
changed = installer.changed;
}
finally {
this._p.next();
}
return this;
return changed;
}

// these are all "package selector based":
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export function readHtmlScripts (source: string, fileName: string) {
}
break;

case 'jspm-cast':
case 'jspm-link':
if (!jspmCast)
jspmCast = true;
break;
Expand All @@ -251,7 +251,7 @@ export function readHtmlScripts (source: string, fileName: string) {
srcStart = script.innerStart;
srcEnd = script.innerEnd;
}
if (!type || type === 'module')
if (!type || type === 'module' || type === 'systemjs-module')
return { src, type, start: script.start, end: script.end, srcStart, srcEnd, integrityStart, integrityEnd, typeStart, typeEnd, jspmCast };
}).filter(script => script);
return {
Expand Down

0 comments on commit 1356299

Please sign in to comment.