UNPKG

textiot

Version:

A framework for building web and native (IoT) Dapps on the IPFS network

103 lines (102 loc) 4.56 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const toposort_1 = __importDefault(require("toposort")); class SchemaMiller { static sortLinksByDependency(links) { // Create an array of [ name, dependency ] for sorting const linkAndDepends = Object.entries(links).map(([name, link]) => { const pair = [name, link.use]; return pair; }); // Sort the array into an execution order const sorted = [...toposort_1.default(linkAndDepends)].reverse(); // Refill the items in the sorted array return (sorted // File is the original form so we don't need a method .filter((name) => { return name !== ':file'; }) // TODO: `Name` should eventually be converted to lowercase .map((name) => ({ name, link: links[name] }))); } static normalizeOptions(info) { const opts = info.opts || {}; // Check for top level opts opts.plaintext = (info.plaintext || false).toString(); opts.pin = (info.pin || false).toString(); return opts; } static resolveDependency(method, payloadsByName) { let use; // Convert 'use' to hash of payload if (method.use && method.use !== ':file') { // TODO: This is a hack, should use multihash JS lib in future use = (method.use.length === 46 && method.use.startsWith('Qm')) ? method.use : payloadsByName.files[method.use].hash; } const resolvedMethod = Object.assign({}, method); resolvedMethod.use = use || ''; return resolvedMethod; } static mill(payload, node, remoteMill) { return __awaiter(this, void 0, void 0, function* () { const dir = { files: {} }; // Traverse the schema and collect generated files if (node.mill) { const normal = SchemaMiller.normalizeOptions(node); const resolved = SchemaMiller.resolveDependency(normal, dir); let form; if (resolved.use) { form = undefined; } else if (typeof payload === 'function') { form = payload(); } else { form = payload; } const file = yield remoteMill(node.mill, resolved, form, {}); dir.files[':single'] = file; } else if (node.links) { // Determine order const steps = SchemaMiller.sortLinksByDependency(node.links); // Send each link // eslint-disable-next-line no-restricted-syntax for (const step of steps) { let form; const normal = SchemaMiller.normalizeOptions(step.link || {}); const resolved = SchemaMiller.resolveDependency(normal, dir); if (resolved.use) { // It's an existing 'file', hash will pass as payload, so don't send file again form = undefined; } else if (typeof payload === 'function') { form = payload(); } else { form = payload; } // Must be synchronous for dependencies const file = yield remoteMill(step.link.mill, resolved, form, {}); dir.files[step.name] = file; } } return dir; }); } } exports.default = SchemaMiller;