{"id":20471358,"url":"https://github.com/statewalker/statewalker-parse-observable","last_synced_at":"2026-04-23T03:33:25.126Z","repository":{"id":64981109,"uuid":"580180734","full_name":"statewalker/statewalker-parse-observable","owner":"statewalker","description":null,"archived":false,"fork":false,"pushed_at":"2024-02-02T16:58:34.000Z","size":31,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-27T04:26:42.274Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/statewalker.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-19T23:08:10.000Z","updated_at":"2022-12-19T23:09:13.000Z","dependencies_parsed_at":"2024-02-02T17:56:55.055Z","dependency_job_id":null,"html_url":"https://github.com/statewalker/statewalker-parse-observable","commit_stats":{"total_commits":15,"total_committers":2,"mean_commits":7.5,"dds":0.06666666666666665,"last_synced_commit":"0bf7153a3fee81c13af4fc32d6d3241270532e38"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/statewalker/statewalker-parse-observable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/statewalker%2Fstatewalker-parse-observable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/statewalker%2Fstatewalker-parse-observable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/statewalker%2Fstatewalker-parse-observable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/statewalker%2Fstatewalker-parse-observable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/statewalker","download_url":"https://codeload.github.com/statewalker/statewalker-parse-observable/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/statewalker%2Fstatewalker-parse-observable/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32165120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T02:19:40.750Z","status":"ssl_error","status_checked_at":"2026-04-23T02:17:55.737Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T14:15:52.476Z","updated_at":"2026-04-23T03:33:25.108Z","avatar_url":"https://github.com/statewalker.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @statewalker/parse-observable\n## Parser for ObservableHQ Cells\n\nThis module contains compiler code for ObservableHQ cells.\n\nCode processing works in two steps. At first step (\"parsing\") text code is transformed to a JSON object with cell functons serialized as a plain text. At the next step (\"compilation\") the JSON description is compiled to real executable code. This separation of steps allows to serialize/deserialize JSON cell descriptions and generate plain javascript for notebooks. Which is very useful for notebooks compilation on the server-side in Node.\n\nMethods defined in this module:\n\n* `parse(code, options)` - parses individual ObservableHQ cells and returns a list of sources for JavaScript functions with associated information (name, dependencies etc); this list can be easily serialized and used later without access to the Observable parser\n* `compile({ cells, runtime, observer, module? })` - returns an object with Observable runtime module and variables\n\n## `parse(code, options)`\n\nThis metdhod parses the given code and returns an array of cells definitions with plain JavaScript code.\nThe resulting cells can be serialized to JSON and used later without access to the ObservableHQ parser.\n\nParameters:\n* `code` - string | Array\u003cstring\u003e - code for one or multiple ObservableHQ cells\n* `options` - options applied directly  to the @observablehq/parse#[parseCell](https://github.com/observablehq/parser#parseCell) method\n\nThis method returns compiled cells in the following format: \n`{ type : \"import\" | \"cell\", ... }`\n\n**`import` items:**\n\n* `type=\"import\"`\n* `source` - source of the import\n* `specifiers` - list of imported variables\n* `injections` - list of variables to re-define in the imported module\n\nEach entry in the `imported` or `injected` arrays has the following structure:\n* `name` - name of the variable (cell) in the imported module\n* `alias` - name of the imported variable in this module; it \"overloads\" the name for the imported variables\nVery often the `name` and `alias` are the same which means that cells in the local and imported modules have the same name.\n\n**`cell` items:**\n* `type=\"cell\"`\n* `name` - name of the cell (variable); example: `viewof ${name}`\n* `references` - list of variables used in this cells; these variables should be provided by the runtime; it could be other cells from this notebook or global variables\n* `code` - plain compiled javascript\n* `constants` - list of \"constants\" used in this cell; it could be an attachment file reference (ex: `FileAttachment(\"AttachmentName\")`) or a secret (ex: `Secret(\"MY_API_KEY\")`)\n\nExample:\n```js\n\nimport { parse } from \"@statewalker/parse-observable\";\n\n// Cells sources\nconst sources = [\n  `message = \"Hello, world!\"`,\n  `element = {\n      const div = document.createElement(\"div\");\n      div.innerHTML = message;\n      return div;\n   }`\n]\n\n// Get a list of all cell javascript sources\nconst cells = parse(sources);\n\n// Output:\n[\n  {\n    \"type\": \"cell\",\n    \"name\": \"message\",\n    \"references\": [],\n    \"code\": 'function message() {\\nreturn (\"Hello, world!\");\\n}',\n  },\n  {\n    \"type\": \"cell\",\n    \"name\": \"element\",\n    \"references\": [ \"message\" ],\n    \"code\":\n      `function element(message) {\n      const div = document.createElement(\"div\");\n      div.innerHTML = message;\n      return div;\n      }`,\n  },\n]\n```\n\n## `compile({ cells, runtime, observer, module?, })`\n\nThis method compiles the specified set of cells to a module and returns an object containing the ObservableHQ module and a list of variables.\n\nParameters:\n * `options` - contains methods used by this function\n * `options.cells` - list of serialized ObservableHQ cells returned by the `parse` method\n * `options.runtime` - the [ObservableHQ Runtime](https://github.com/observablehq/runtime#Runtime) used to create modules and variables\n * `options.observer` - the [ObservableHQ Observer](https://github.com/observablehq/runtime#observers) function returning instances tracking the lifecycle of individual variables (should contain \"pending\"/\"fulfilled\"/\"rejected\" methods)\n * `options.module` [optional] - an [ObservableHQ Module](https://github.com/observablehq/runtime#modules) instance containing the returned variables; if this parameter is not defined then this method will create a new module\n * `options.resolve` [optional] - this async method should resolve the specified import and return the corresponding ObservableHQ Module; default function: {@link #resolveImportSource}\n * `options.compileCell` [optional] - this function compiles the code of the given cell; by default it is the {@link #compileCellCode} function\n * `options.formatImport` [optional] - this method formats the specified import cell to visualize import in the main module; by default it uses the {@link #formatImportCell} method.\n\n This method returns a `Promise` resolving to an object with the following fields:\n * \"variables\" - list of [ObservableHQ Variable](https://github.com/observablehq/runtime#variables) instances\n * \"module\" - [ObservableHQ Module](https://github.com/observablehq/runtime#modules) used to create variables; if the \"module\" parameter for this function was defined then it is the same instance\n\n\n```js\nimport { Runtime, Inspector } from \"@observablehq/parser\";\nimport { parse, compile, resolveImportSource, compileCellCode } from \"@statewalker/parse-observable\";\n\n// This method is responsible for calling individual cell methods.\n// It can re-define the context ('this') of these methods.\nconst cells = parse([`...code source...`]);\nconst observer = (name) =\u003e {\n  let elm = document.querySelector('#' + name);\n  if (!elm) {\n    elm = document.createElement(\"div\");\n    document.body.appendChild(elm);\n  }\n  return new Inspector(elm);\n}; \nconst { module, variables } = await compile({\n  cells,                          // Parsed cells\n  observer,                       // Observer attaching cells to DOM\n  runtime: new Runtime(),         // ObservableHQ Runtime \n  compileCell : compileCellCode   // Cells code compiler; Default value\n  resolve: resolveImportSource,   // Import of external notebooks; Default value\n});\n\n...\n```\n\nThe `compileCell` parameter allows to re-define the default execution context for cells:\n\n```js\n\nconst context = { ... };\nconst compileCell = ({ cell }) =\u003e {\n  let method = new Function(`\"use strict\"\\nreturn (${cell.code})`)();\n  return (...args) =\u003e method.apply(context, args);\n};\n\n```\n\n\nExample:\n```js\nimport { parse, newCompiler } from \"@statewalker/parse-observable\";\nimport { Runtime } from \"@observablehq/runtime\";\n\nconst cells = parse([\n  `mutable myA = 'aa'`,\n  `{ mutable myA = 'Hello, world!' }`,\n]);\nconst context = { };\nconst { variables, module } = compile({\n  cells,\n  resolve: () =\u003e {},\n  runtime: new Runtime(),\n  observer: () =\u003e true, // Just to be sure that all cells are evaluated\n  compileCell : ({ cell }) =\u003e {\n    let method = new Function(`\"use strict\"\\nreturn (${cell.code})`)();\n    return (...args) =\u003e method.apply(context, args);\n  },\n});\nconst value = await compiled.value(\"myA\");\nconsole.log(value);\n// Output: \"Hello, world!\"\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatewalker%2Fstatewalker-parse-observable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstatewalker%2Fstatewalker-parse-observable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatewalker%2Fstatewalker-parse-observable/lists"}