Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ellx/framework

Package Overview
Dependencies
Maintainers
2
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ellx/framework - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

src/build_n_serve.js

5

package.json
{
"name": "@ellx/framework",
"version": "0.0.1",
"version": "0.0.2",
"description": "Ellx full stack framework",

@@ -25,5 +25,5 @@ "type": "module",

"md5": "^2.3.0",
"mime": "^3.0.0",
"node-resolve-flow": "^0.8.0",
"open": "^8.4.0",
"polka": "^0.5.2",
"qcjs": "^0.1.0",

@@ -34,3 +34,2 @@ "quarx": "^5, >=5.4.1",

"rd-parse-jsexpr": "^3.2.0",
"serve-static": "^1.15.0",
"ws": "^8.11.0"

@@ -37,0 +36,0 @@ },

13

src/bundler/module_loader.js

@@ -5,2 +5,3 @@ import { transform as esm2cjs } from 'qcjs';

const scriptTags = /(<script type="ellx">|<\/script>)/g;
export const assetHrefs = /\b(href|src)="(\/assets\/[^"]+)"/g;

@@ -27,13 +28,11 @@ export function transformModule(id, text) {

const assets = [...text.matchAll(assetHrefs)].map(([,, path]) => 'file://' + path);
return {
code: `<!--${id}-->` + text,
imports
code: text,
imports,
assets
}
}
else if (id.endsWith('.css')) {
return {
code: { exports: text },
}
}
return esm2cjs(text);
}

@@ -8,11 +8,8 @@ import { createAtom } from 'quarx';

export default function reactiveBuild(mainPage, files, updateModules) {
const styleSheet = new URL('./styles.css', mainPage).href;
export default function reactiveBuild(mainPageId, entryPointId, rfs, updateModules) {
const entryPoints = [
mainPage,
styleSheet,
mainPageId,
entryPointId,
'conclure',
'node-resolve-flow',
'./src/runtime/dev/dev_runtime.js'
'node-resolve-flow'
];

@@ -23,11 +20,14 @@

function* loadPkgJSON(url) {
const pjsonBody = yield files.get(url);
const pjson = pjsonBody && JSON.parse(pjsonBody);
const pjsonBody = yield rfs.get(url);
const pjson = pjsonBody && JSON.parse(pjsonBody.toString('utf8'));
bundle[url] = pjson && {
code: { exports: pjson },
imports: {}
};
if (!pjson) return null;
return pjson;
const pruned = {};
for (let p of ['name', 'exports', 'imports', 'browser', 'main']) {
if (p in pjson) pruned[p] = pjson[p];
}
bundle[url] = { code: { exports: pruned } };
return pruned;
}

@@ -40,3 +40,3 @@

const body = yield files.get(url);
const body = yield rfs.get(url);

@@ -51,7 +51,8 @@ if (body === undefined) {

return bundle[url] = transformModule(url, body);
return bundle[url] = url.startsWith('file:///assets/') ? body :
transformModule(url, body.toString('utf8'));
});
const resolveId = resolver({
isFile: url => files.has(url),
isFile: url => rfs.has(url),
loadPkgJSON: autoMemo(loadPkgJSON)

@@ -83,2 +84,3 @@ });

.map(module => loadModule(module, id, loadStack))
.concat((node.assets || []).map(load))
);

@@ -85,0 +87,0 @@

@@ -25,3 +25,3 @@ import chokidar from 'chokidar';

const load = path => fs.readFile(path, 'utf8')
const load = path => fs.readFile(path)
.catch((e) => undefined);

@@ -28,0 +28,0 @@

#!/usr/bin/env node
import http from "http";
import { WebSocketServer } from "ws";
import commandLineArgs from "command-line-args";
import { start, build } from "./build_n_serve.js";
import { pathToFileURL, fileURLToPath } from 'url';
import { join, dirname } from "path";
import { readFileSync } from 'fs';
import polka from "polka";
import serve from "serve-static";
import open from "open";
import reactiveFS from './bundler/reactive_fs.js';
import { startDevPipe } from "./dev_pipe.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
// 1) - parse the main command

@@ -32,3 +18,3 @@

{ name: "port", alias: "p", type: Number, defaultValue: 3002 },
{ name: "open", alias: "o", type: Boolean, defaultValue: true },
{ name: "open", alias: "o", type: Boolean, defaultValue: false },
];

@@ -38,38 +24,14 @@

const devIndex = readFileSync(join(__dirname, 'dev_index.html'), 'utf8');
const server = http.createServer();
polka({ server })
.use(serve(process.cwd()))
.get("*", (req, res, next) => res.end(devIndex))
.listen(config.port, (err) => {
if (err) throw err;
const url = `http://localhost:${config.port}`;
console.log(`> Running on ${url}`);
if (config.open) {
open(url).catch(console.error);
}
});
const wss = new WebSocketServer({ server, path: "/@@dev" });
const rfs = reactiveFS(process.cwd(), { logger: console.log });
wss.on('connection', ws => startDevPipe(
ws,
rfs,
'file:///src/index.html'
).catch(console.error));
start(process.cwd(), config);
}
else if (mainOptions.command === 'build') {
build(process.cwd());
}
else {
console.log(`Please specify a command:
dev
build
login (WIP)
publish (WIP)
deploy (WIP)
`);
process.exit(1);
}

@@ -1,6 +0,4 @@

import { writeFile, mkdir } from 'fs/promises';
import { writeFile, mkdir, rm } from 'fs/promises';
import { join } from 'path';
import { fileURLToPath } from 'url';
import md5 from 'md5';
import { all } from 'conclure/combinators';

@@ -11,3 +9,3 @@ async function makeOne(filePath, contents, secondTry = false) {

if (filePath.endsWith('/')) await mkdir(filePath);
else await writeFile(filePath, contents, 'utf8');
else await writeFile(filePath, contents);
}

@@ -25,13 +23,13 @@ catch (e) {

export function* copyToDist(distDir, modules) {
yield rmdir(distDir, { recursive: true });
export async function copyToDist(distDir, artefacts) {
try {
await rm(distDir, { recursive: true });
}
catch (e) {
if (e.code !== 'ENOENT') throw e;
}
yield all(Object.entries(modules).map(([urlPath, body]) => {
if (urlPath !== 'file:///index.html') {
const hash = md5(body).slice(0, 8);
urlPath = urlPath.replace(/\.[^.]*$/, ext => '-' + hash + ext);
}
return makeOne(join(distDir, fileURLToPath(urlPath)), body);
}));
await Promise.all(Object.entries(artefacts)
.map(([url, body]) => makeOne(join(distDir, fileURLToPath(url)), body))
);
}

@@ -1,2 +0,2 @@

export function bootstrap(modules, entryPoint, ...args) {
export function bootstrap(modules, { conclureId, resolverId, mainPageId, entryPoint }) {
console.debug('***Initial modules***', modules);

@@ -7,5 +7,5 @@

for (let url in modules) {
const { src, code } = modules[url];
const src = modules[url];
const source = src ? fetch(src).then(res => res.text()) : code;
const source = typeof src === 'string' ? fetch(url.slice(7) + '?h=' + src).then(res => res.text()) : src;
registry.set(url, createModuleNode(url, source));

@@ -94,4 +94,4 @@ }

const { conclude, isFlow } = requireNode(Object.keys(modules).find(id => id.endsWith('/node_modules/conclure/src/conclude.js')));
const { default: makeResolve } = requireNode(Object.keys(modules).find(id => id.endsWith('/node_modules/node-resolve-flow/src/resolver.js')));
const { conclude, isFlow } = requireNode(conclureId);
const { default: makeResolve } = requireNode(resolverId);

@@ -140,4 +140,5 @@ const toAsync = f => function* (...args) {

if (error) console.error(error.stack);
init.default(...args);
init.default(mainPageId);
});
}
import { autorun, batch, createAtom } from 'quarx';
import { box } from 'quarx/box';
import { observableMap } from 'quarx/map';
import { hydrate, cannotResolve } from '../dom_attach.js';
import hydrateDocument from '../dom_attach.js';
function replaceDocumentHTML(id, html) {
function replaceDocumentHTML(html) {
document.open();
document.write(html);
document.close();
const require = url => module.requireAsync(url, id);
const children = [...document.head.children, ...document.body.children];
return hydrate(children, name => ({ require })[name] || cannotResolve(name));
}

@@ -50,10 +45,5 @@

export default function init(devServer) {
export default function init(mainPageId) {
const proto = Object.getPrototypeOf(module);
const mainPage = 'file:///src/index.html';
if (!proto.registry.has(mainPage)) {
throw new Error(`Main page ${mainPage} not found`);
}
for (let [id, node] of proto.registry) {

@@ -70,4 +60,4 @@ makeInstanceReactive(id, node);

for (let id in modules) {
if (id.endsWith('.css')) updateStyles(id);
else if (modules[id] === 'deleted') proto.registry.delete(id);
if (modules[id] === 'deleted') proto.registry.delete(id);
else if (id.startsWith('file:///assets/')) updateAsset(id, modules[id]);
else proto.registry.set(id, makeInstanceReactive(id, proto.createNode(id, modules[id].code)));

@@ -79,11 +69,10 @@ }

function updateStyles(id) {
console.debug('***STYLESHEET update***', id);
function updateAsset(id, hash) {
console.debug('***ASSET update***', id);
const url = id.slice(7);
const styleSheet = document.querySelector(`link[rel="stylesheet"][href^=${JSON.stringify(url)}]`);
if (styleSheet) {
styleSheet.href = url + '?reload' + Math.random();
}
else console.error('STYLESHET not loaded', id);
['href', 'src'].forEach(attr =>
document.querySelectorAll(`[${attr}^="${url}"]`)
.forEach(asset => asset[attr] = url + '?h=' + hash)
);
}

@@ -111,2 +100,4 @@

const devServer = new WebSocket(window.location.origin.replace(/^http/, 'ws') + '/@@dev');
devServer.addEventListener('message', listen);

@@ -135,3 +126,3 @@ devServer.addEventListener('close', disconnect);

`<pre style="color:red">${error}</pre>` :
proto.registry.get(mainPage).instance.exports.default;
proto.registry.get(mainPageId)?.instance.exports.default;

@@ -141,5 +132,8 @@ // Inserting a tick here ensures that everything becomes unobserved and

Promise.resolve().then(() =>
off = replaceDocumentHTML(mainPage, html)
);
Promise.resolve().then(() => {
if (html !== undefined) {
replaceDocumentHTML(html);
}
off = hydrateDocument(mainPageId);
});
}, { name: 'replaceDocumentHTML' }));

@@ -146,0 +140,0 @@

@@ -5,6 +5,13 @@ import { calcNode } from '@ellx/core';

export const cannotResolve = name => {
const cannotResolve = name => {
throw new Error(`Cannot resolve ${name}`);
}
export default function hydrateDocument(mainPageId) {
const require = url => module.requireAsync(url, mainPageId);
const children = [...document.head.children, ...document.body.children];
return hydrate(children, name => ({ require })[name] || cannotResolve(name));
}
function bindInnerHTML(element, resolve) {

@@ -244,3 +251,3 @@ const { component, props } = parseIsComponent(element.dataset.is);

export function hydrate(children, resolve) {
function hydrate(children, resolve) {
const subscriptions = [];

@@ -247,0 +254,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc