From d50aa7d4e66cb18350dd505b08300d0d248ca142 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 13:45:54 +0800 Subject: [PATCH 01/16] Initialize spago@next --- spago.lock | 1105 ++++++++++++++++++++++++++++++++++++++++++++++++++++ spago.yaml | 22 ++ 2 files changed, 1127 insertions(+) create mode 100644 spago.lock create mode 100644 spago.yaml diff --git a/spago.lock b/spago.lock new file mode 100644 index 0000000..a123333 --- /dev/null +++ b/spago.lock @@ -0,0 +1,1105 @@ +workspace: + packages: + halogen-vdom: + path: ./ + dependencies: + - bifunctors + - console + - effect + - exists + - foreign + - foreign-object + - maybe + - prelude + - refs + - tuples + - unsafe-coerce + - web-html + test_dependencies: [] + build_plan: + - arrays + - bifunctors + - console + - const + - contravariant + - control + - datetime + - distributive + - effect + - either + - enums + - exceptions + - exists + - foldable-traversable + - foreign + - foreign-object + - functions + - functors + - gen + - identity + - integers + - invariant + - js-date + - lazy + - lists + - maybe + - media-types + - newtype + - nonempty + - now + - nullable + - numbers + - ordered-collections + - orders + - partial + - prelude + - profunctor + - refs + - safe-coerce + - st + - strings + - tailrec + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unsafe-coerce + - web-dom + - web-events + - web-file + - web-html + - web-storage + package_set: + address: + registry: 51.2.0 + compiler: ">=0.15.15 <0.16.0" + content: + abc-parser: 2.0.1 + ace: 9.1.0 + address-rfc2821: 0.1.1 + aff: 7.1.0 + aff-bus: 6.0.0 + aff-coroutines: 9.0.0 + aff-promise: 4.0.0 + aff-retry: 2.0.0 + affjax: 13.0.0 + affjax-node: 1.0.0 + affjax-web: 1.0.0 + ansi: 7.0.0 + apexcharts: 0.5.0 + applicative-phases: 1.0.0 + argonaut: 9.0.0 + argonaut-aeson-generic: 0.4.1 + argonaut-codecs: 9.1.0 + argonaut-core: 7.0.0 + argonaut-generic: 8.0.0 + argonaut-traversals: 10.0.0 + argparse-basic: 2.0.0 + array-builder: 0.1.2 + array-search: 0.5.6 + arraybuffer: 13.2.0 + arraybuffer-builder: 3.1.0 + arraybuffer-types: 3.0.2 + arrays: 7.3.0 + arrays-extra: 0.6.1 + arrays-zipper: 2.0.1 + ask: 1.0.0 + assert: 6.0.0 + assert-multiple: 0.3.4 + avar: 5.0.0 + b64: 0.0.8 + barbies: 1.0.1 + barlow-lens: 0.9.0 + bifunctors: 6.0.0 + bigints: 7.0.1 + bolson: 0.3.9 + bookhound: 0.1.7 + bower-json: 3.0.0 + call-by-name: 4.0.1 + canvas: 6.0.0 + canvas-action: 9.0.0 + cartesian: 1.0.6 + catenable-lists: 7.0.0 + cbor-stream: 1.0.4 + chameleon: 1.0.0 + chameleon-halogen: 1.0.3 + chameleon-react-basic: 1.1.0 + chameleon-styled: 2.5.0 + chameleon-transformers: 1.0.0 + channel: 1.0.0 + checked-exceptions: 3.1.1 + choku: 1.0.1 + classless: 0.1.1 + classless-arbitrary: 0.1.1 + classless-decode-json: 0.1.1 + classless-encode-json: 0.1.3 + classnames: 2.0.0 + codec: 6.1.0 + codec-argonaut: 10.0.0 + codec-json: 1.2.0 + colors: 7.0.1 + concur-core: 0.5.0 + concur-react: 0.5.0 + concurrent-queues: 3.0.0 + console: 6.1.0 + const: 6.0.0 + contravariant: 6.0.0 + control: 6.0.0 + convertable-options: 1.0.0 + coroutines: 7.0.0 + css: 6.0.0 + css-frameworks: 1.0.1 + csv-stream: 2.0.2 + data-mvc: 0.0.2 + datetime: 6.1.0 + datetime-parsing: 0.2.0 + debounce: 0.1.0 + debug: 6.0.2 + decimals: 7.1.0 + default-values: 1.0.1 + deku: 0.9.23 + deno: 0.0.5 + dissect: 1.0.0 + distributive: 6.0.0 + dom-filereader: 7.0.0 + dom-indexed: 12.0.0 + dom-simple: 0.4.0 + dotenv: 4.0.3 + droplet: 0.6.0 + dts: 1.0.0 + dual-numbers: 1.0.2 + dynamic-buffer: 3.0.1 + echarts-simple: 0.0.1 + effect: 4.0.0 + either: 6.1.0 + elmish: 0.11.3 + elmish-enzyme: 0.1.1 + elmish-hooks: 0.10.0 + elmish-html: 0.8.2 + elmish-testing-library: 0.3.2 + email-validate: 7.0.0 + encoding: 0.0.9 + enums: 6.0.1 + env-names: 0.3.4 + error: 2.0.0 + eta-conversion: 0.3.2 + exceptions: 6.0.0 + exists: 6.0.0 + exitcodes: 4.0.0 + expect-inferred: 3.0.0 + ezfetch: 1.0.0 + fahrtwind: 2.0.0 + fallback: 0.1.0 + fast-vect: 1.2.0 + fetch: 4.1.0 + fetch-argonaut: 1.0.1 + fetch-core: 5.1.0 + fetch-yoga-json: 1.1.0 + ffi-simple: 0.5.1 + fft-js: 0.1.0 + filterable: 5.0.0 + fix-functor: 0.1.0 + fixed-points: 7.0.0 + fixed-precision: 5.0.0 + flame: 1.3.0 + float32: 2.0.0 + fmt: 0.2.1 + foldable-traversable: 6.0.0 + foldable-traversable-extra: 0.0.6 + foreign: 7.0.0 + foreign-object: 4.1.0 + foreign-readwrite: 3.4.0 + forgetmenot: 0.1.0 + fork: 6.0.0 + form-urlencoded: 7.0.0 + formatters: 7.0.0 + framer-motion: 1.0.1 + free: 7.1.0 + freeap: 7.0.0 + freer-free: 0.0.1 + freet: 7.0.0 + functions: 6.0.0 + functor1: 3.0.0 + functors: 5.0.0 + fuzzy: 0.4.0 + gen: 4.0.0 + generate-values: 1.0.1 + generic-router: 0.0.1 + geojson: 0.0.5 + geometry-plane: 1.0.3 + gojs: 0.1.1 + grain: 3.0.0 + grain-router: 3.0.0 + grain-virtualized: 3.0.0 + graphs: 8.1.0 + group: 4.1.1 + halogen: 7.0.0 + halogen-bootstrap5: 5.3.2 + halogen-canvas: 1.0.0 + halogen-css: 10.0.0 + halogen-echarts-simple: 0.0.4 + halogen-formless: 4.0.3 + halogen-helix: 1.0.0 + halogen-hooks: 0.6.3 + halogen-hooks-extra: 0.9.0 + halogen-infinite-scroll: 1.1.0 + halogen-store: 0.5.4 + halogen-storybook: 2.0.0 + halogen-subscriptions: 2.0.0 + halogen-svg-elems: 8.0.0 + halogen-typewriter: 1.0.4 + halogen-vdom: 8.0.0 + halogen-vdom-string-renderer: 0.5.0 + halogen-xterm: 2.0.0 + heckin: 2.0.1 + heterogeneous: 0.6.0 + homogeneous: 0.4.0 + http-methods: 6.0.0 + httpurple: 4.0.0 + humdrum: 0.0.1 + hyrule: 2.3.8 + identity: 6.0.0 + identy: 4.0.1 + indexed-db: 1.0.0 + indexed-monad: 3.0.0 + int64: 3.0.0 + integers: 6.0.0 + interpolate: 5.0.2 + intersection-observer: 1.0.1 + invariant: 6.0.0 + jarilo: 1.0.1 + jelly: 0.10.0 + jelly-router: 0.3.0 + jelly-signal: 0.4.0 + jest: 1.0.0 + js-abort-controller: 1.0.0 + js-bigints: 2.2.1 + js-date: 8.0.0 + js-fetch: 0.2.1 + js-fileio: 3.0.0 + js-intl: 1.0.4 + js-iterators: 0.1.1 + js-maps: 0.1.2 + js-promise: 1.0.0 + js-promise-aff: 1.0.0 + js-timers: 6.1.0 + js-uri: 3.1.0 + json: 1.1.0 + json-codecs: 5.0.0 + justifill: 0.5.0 + jwt: 0.0.9 + labeled-data: 0.2.0 + language-cst-parser: 0.14.0 + lazy: 6.0.0 + lazy-joe: 1.0.0 + lcg: 4.0.0 + leibniz: 5.0.0 + leveldb: 1.0.1 + liminal: 1.0.1 + linalg: 6.0.0 + lists: 7.0.0 + literals: 1.0.2 + logging: 3.0.0 + logging-journald: 0.4.0 + lumi-components: 18.0.0 + machines: 7.0.0 + maps-eager: 0.4.1 + marionette: 1.0.0 + marionette-react-basic-hooks: 0.1.1 + marked: 0.1.0 + matrices: 5.0.1 + matryoshka: 1.0.0 + maybe: 6.0.0 + media-types: 6.0.0 + meowclient: 1.0.0 + midi: 4.0.0 + milkis: 9.0.0 + minibench: 4.0.1 + mmorph: 7.0.0 + monad-control: 5.0.0 + monad-logger: 1.3.1 + monad-loops: 0.5.0 + monad-unlift: 1.0.1 + monoid-extras: 0.0.1 + monoidal: 0.16.0 + morello: 0.4.0 + mote: 3.0.0 + motsunabe: 2.0.0 + mvc: 0.0.1 + mysql: 6.0.1 + n3: 0.1.0 + nano-id: 1.1.0 + nanoid: 0.1.0 + naturals: 3.0.0 + nested-functor: 0.2.1 + newtype: 5.0.0 + nextjs: 0.1.1 + nextui: 0.2.0 + node-buffer: 9.0.0 + node-child-process: 11.1.0 + node-event-emitter: 3.0.0 + node-execa: 5.0.0 + node-fs: 9.1.0 + node-glob-basic: 1.3.0 + node-http: 9.1.0 + node-http2: 1.1.1 + node-human-signals: 1.0.0 + node-net: 5.1.0 + node-os: 5.1.0 + node-path: 5.0.0 + node-process: 11.2.0 + node-readline: 8.1.0 + node-sqlite3: 8.0.0 + node-stream-pipes: 1.4.1 + node-streams: 9.0.0 + node-tls: 0.3.1 + node-url: 7.0.1 + node-zlib: 0.4.0 + nonempty: 7.0.0 + now: 6.0.0 + npm-package-json: 2.0.0 + nullable: 6.0.0 + numberfield: 0.1.0 + numbers: 9.0.1 + oak: 3.1.1 + oak-debug: 1.2.2 + object-maps: 0.3.0 + ocarina: 1.5.4 + open-folds: 6.3.0 + open-memoize: 6.1.0 + open-pairing: 6.1.0 + options: 7.0.0 + optparse: 5.0.1 + ordered-collections: 3.2.0 + ordered-set: 0.4.0 + orders: 6.0.0 + owoify: 1.2.0 + pairs: 9.0.1 + parallel: 7.0.0 + parsing: 10.2.0 + parsing-dataview: 3.2.4 + partial: 4.0.0 + pathy: 9.0.0 + pha: 0.13.0 + phaser: 0.7.0 + phylio: 1.1.2 + pipes: 8.0.0 + pirates-charm: 0.0.1 + pmock: 0.9.0 + point-free: 1.0.0 + pointed-list: 0.5.1 + polymorphic-vectors: 4.0.0 + posix-types: 6.0.0 + postgresql: 1.6.3 + precise: 6.0.0 + precise-datetime: 7.0.0 + prelude: 6.0.1 + prettier-printer: 3.0.0 + profunctor: 6.0.1 + profunctor-lenses: 8.0.0 + protobuf: 4.3.0 + psa-utils: 8.0.0 + psci-support: 6.0.0 + punycode: 1.0.0 + qualified-do: 2.2.0 + quantities: 12.2.0 + quickcheck: 8.0.1 + quickcheck-combinators: 0.1.3 + quickcheck-laws: 7.0.0 + quickcheck-utf8: 0.0.0 + random: 6.0.0 + rationals: 6.0.0 + rdf: 0.1.0 + react: 11.0.0 + react-aria: 0.2.0 + react-basic: 17.0.0 + react-basic-classic: 3.0.0 + react-basic-dnd: 10.1.0 + react-basic-dom: 6.1.0 + react-basic-emotion: 7.1.0 + react-basic-hooks: 8.2.0 + react-basic-storybook: 2.0.0 + react-dom: 8.0.0 + react-halo: 3.0.0 + react-icons: 1.1.5 + react-markdown: 0.1.0 + react-testing-library: 4.0.1 + react-virtuoso: 1.0.0 + reactix: 0.6.1 + read: 1.0.1 + recharts: 1.1.0 + record: 4.0.0 + record-extra: 5.0.1 + record-ptional-fields: 0.1.2 + record-studio: 1.0.4 + refs: 6.0.0 + remotedata: 5.0.1 + resize-observer: 1.0.0 + resource: 2.0.1 + resourcet: 1.0.0 + result: 1.0.3 + return: 0.2.0 + ring-modules: 5.0.1 + rito: 0.3.4 + rough-notation: 1.0.2 + routing: 11.0.0 + routing-duplex: 0.7.0 + run: 5.0.0 + safe-coerce: 2.0.0 + safely: 4.0.1 + school-of-music: 1.3.0 + selection-foldable: 0.2.0 + selective-functors: 1.0.1 + semirings: 7.0.0 + signal: 13.0.0 + simple-emitter: 3.0.1 + simple-i18n: 2.0.1 + simple-json: 9.0.0 + simple-json-generics: 0.2.1 + simple-ulid: 3.0.0 + sized-matrices: 1.0.0 + sized-vectors: 5.0.2 + slug: 3.0.8 + small-ffi: 4.0.1 + soundfonts: 4.1.0 + sparse-matrices: 1.3.0 + sparse-polynomials: 2.0.5 + spec: 7.6.0 + spec-mocha: 5.1.0 + spec-quickcheck: 5.0.0 + splitmix: 2.1.0 + ssrs: 1.0.0 + st: 6.2.0 + statistics: 0.3.2 + strictlypositiveint: 1.0.1 + string-parsers: 8.0.0 + strings: 6.0.1 + strings-extra: 4.0.0 + stringutils: 0.0.12 + substitute: 0.2.3 + supply: 0.2.0 + svg-parser: 3.0.0 + systemd-journald: 0.3.0 + tagged: 4.0.2 + tailrec: 6.1.0 + tecton: 0.2.1 + tecton-halogen: 0.2.0 + test-unit: 17.0.0 + thermite: 6.3.1 + thermite-dom: 0.3.1 + these: 6.0.0 + toestand: 0.9.0 + transformation-matrix: 1.0.1 + transformers: 6.0.0 + tree-rose: 4.0.2 + ts-bridge: 4.0.0 + tuples: 7.0.0 + two-or-more: 1.0.0 + type-equality: 4.0.1 + typedenv: 2.0.1 + typelevel: 6.0.0 + typelevel-lists: 2.1.0 + typelevel-peano: 1.0.1 + typelevel-prelude: 7.0.0 + typelevel-regex: 0.0.3 + typelevel-rows: 0.1.0 + typisch: 0.4.0 + uint: 7.0.0 + ulid: 3.0.1 + uncurried-transformers: 1.1.0 + undefined: 2.0.0 + undefined-is-not-a-problem: 1.1.0 + unfoldable: 6.0.0 + unicode: 6.0.0 + unique: 0.6.1 + unlift: 1.0.1 + unordered-collections: 3.1.0 + unsafe-coerce: 6.0.0 + unsafe-reference: 5.0.0 + untagged-to-tagged: 0.1.4 + untagged-union: 1.0.0 + uri: 9.0.0 + url-immutable: 1.0.0 + uuid: 9.0.0 + uuidv4: 1.0.0 + validation: 6.0.0 + variant: 8.0.0 + variant-encodings: 2.0.0 + vectorfield: 1.0.1 + vectors: 2.1.0 + versions: 7.0.0 + visx: 0.0.2 + web-clipboard: 5.0.0 + web-cssom: 2.0.0 + web-cssom-view: 0.1.0 + web-dom: 6.0.0 + web-dom-parser: 8.0.0 + web-dom-xpath: 3.0.0 + web-encoding: 3.0.0 + web-events: 4.0.0 + web-fetch: 4.0.1 + web-file: 4.0.0 + web-geometry: 0.1.0 + web-html: 4.1.0 + web-pointerevents: 2.0.0 + web-proletarian: 1.0.0 + web-promise: 3.2.0 + web-resize-observer: 2.1.0 + web-router: 1.0.0 + web-socket: 4.0.0 + web-storage: 5.0.0 + web-streams: 4.0.0 + web-touchevents: 4.0.0 + web-uievents: 5.0.0 + web-url: 2.0.0 + web-workers: 1.1.0 + web-xhr: 5.0.1 + webextension-polyfill: 0.1.0 + webgpu: 0.0.1 + which: 2.0.0 + xterm: 1.0.0 + yoga-fetch: 1.0.1 + yoga-json: 5.1.0 + yoga-om: 0.1.0 + yoga-postgres: 6.0.0 + yoga-tree: 1.0.0 + z3: 0.0.2 + zipperarray: 2.0.0 + extra_packages: {} +packages: + arrays: + type: registry + version: 7.3.0 + integrity: sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc= + dependencies: + - bifunctors + - control + - foldable-traversable + - functions + - maybe + - nonempty + - partial + - prelude + - safe-coerce + - st + - tailrec + - tuples + - unfoldable + - unsafe-coerce + bifunctors: + type: registry + version: 6.0.0 + integrity: sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw= + dependencies: + - const + - either + - newtype + - prelude + - tuples + console: + type: registry + version: 6.1.0 + integrity: sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM= + dependencies: + - effect + - prelude + const: + type: registry + version: 6.0.0 + integrity: sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc= + dependencies: + - invariant + - newtype + - prelude + contravariant: + type: registry + version: 6.0.0 + integrity: sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c= + dependencies: + - const + - either + - newtype + - prelude + - tuples + control: + type: registry + version: 6.0.0 + integrity: sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk= + dependencies: + - newtype + - prelude + datetime: + type: registry + version: 6.1.0 + integrity: sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI= + dependencies: + - bifunctors + - control + - either + - enums + - foldable-traversable + - functions + - gen + - integers + - lists + - maybe + - newtype + - numbers + - ordered-collections + - partial + - prelude + - tuples + distributive: + type: registry + version: 6.0.0 + integrity: sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ= + dependencies: + - identity + - newtype + - prelude + - tuples + - type-equality + effect: + type: registry + version: 4.0.0 + integrity: sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M= + dependencies: + - prelude + either: + type: registry + version: 6.1.0 + integrity: sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY= + dependencies: + - control + - invariant + - maybe + - prelude + enums: + type: registry + version: 6.0.1 + integrity: sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8= + dependencies: + - control + - either + - gen + - maybe + - newtype + - nonempty + - partial + - prelude + - tuples + - unfoldable + exceptions: + type: registry + version: 6.0.0 + integrity: sha256-y/xTAEIZIARCE+50/u1di0ncebJ+CIwNOLswyOWzMTw= + dependencies: + - effect + - either + - maybe + - prelude + exists: + type: registry + version: 6.0.0 + integrity: sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8= + dependencies: + - unsafe-coerce + foldable-traversable: + type: registry + version: 6.0.0 + integrity: sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM= + dependencies: + - bifunctors + - const + - control + - either + - functors + - identity + - maybe + - newtype + - orders + - prelude + - tuples + foreign: + type: registry + version: 7.0.0 + integrity: sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA= + dependencies: + - either + - functions + - identity + - integers + - lists + - maybe + - prelude + - strings + - transformers + foreign-object: + type: registry + version: 4.1.0 + integrity: sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo= + dependencies: + - arrays + - foldable-traversable + - functions + - gen + - lists + - maybe + - prelude + - st + - tailrec + - tuples + - typelevel-prelude + - unfoldable + functions: + type: registry + version: 6.0.0 + integrity: sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI= + dependencies: + - prelude + functors: + type: registry + version: 5.0.0 + integrity: sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU= + dependencies: + - bifunctors + - const + - contravariant + - control + - distributive + - either + - invariant + - maybe + - newtype + - prelude + - profunctor + - tuples + - unsafe-coerce + gen: + type: registry + version: 4.0.0 + integrity: sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI= + dependencies: + - either + - foldable-traversable + - identity + - maybe + - newtype + - nonempty + - prelude + - tailrec + - tuples + - unfoldable + identity: + type: registry + version: 6.0.0 + integrity: sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY= + dependencies: + - control + - invariant + - newtype + - prelude + integers: + type: registry + version: 6.0.0 + integrity: sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158= + dependencies: + - maybe + - numbers + - prelude + invariant: + type: registry + version: 6.0.0 + integrity: sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo= + dependencies: + - control + - prelude + js-date: + type: registry + version: 8.0.0 + integrity: sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo= + dependencies: + - datetime + - effect + - exceptions + - foreign + - integers + - now + lazy: + type: registry + version: 6.0.0 + integrity: sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU= + dependencies: + - control + - foldable-traversable + - invariant + - prelude + lists: + type: registry + version: 7.0.0 + integrity: sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI= + dependencies: + - bifunctors + - control + - foldable-traversable + - lazy + - maybe + - newtype + - nonempty + - partial + - prelude + - tailrec + - tuples + - unfoldable + maybe: + type: registry + version: 6.0.0 + integrity: sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q= + dependencies: + - control + - invariant + - newtype + - prelude + media-types: + type: registry + version: 6.0.0 + integrity: sha256-n/4FoGBasbVSYscGVRSyBunQ6CZbL3jsYL+Lp01mc9k= + dependencies: + - newtype + - prelude + newtype: + type: registry + version: 5.0.0 + integrity: sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw= + dependencies: + - prelude + - safe-coerce + nonempty: + type: registry + version: 7.0.0 + integrity: sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs= + dependencies: + - control + - foldable-traversable + - maybe + - prelude + - tuples + - unfoldable + now: + type: registry + version: 6.0.0 + integrity: sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY= + dependencies: + - datetime + - effect + nullable: + type: registry + version: 6.0.0 + integrity: sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o= + dependencies: + - effect + - functions + - maybe + numbers: + type: registry + version: 9.0.1 + integrity: sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk= + dependencies: + - functions + - maybe + ordered-collections: + type: registry + version: 3.2.0 + integrity: sha256-o9jqsj5rpJmMdoe/zyufWHFjYYFTTsJpgcuCnqCO6PM= + dependencies: + - arrays + - foldable-traversable + - gen + - lists + - maybe + - partial + - prelude + - st + - tailrec + - tuples + - unfoldable + orders: + type: registry + version: 6.0.0 + integrity: sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink= + dependencies: + - newtype + - prelude + partial: + type: registry + version: 4.0.0 + integrity: sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4= + dependencies: [] + prelude: + type: registry + version: 6.0.1 + integrity: sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0= + dependencies: [] + profunctor: + type: registry + version: 6.0.1 + integrity: sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk= + dependencies: + - control + - distributive + - either + - exists + - invariant + - newtype + - prelude + - tuples + refs: + type: registry + version: 6.0.0 + integrity: sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s= + dependencies: + - effect + - prelude + safe-coerce: + type: registry + version: 2.0.0 + integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU= + dependencies: + - unsafe-coerce + st: + type: registry + version: 6.2.0 + integrity: sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY= + dependencies: + - partial + - prelude + - tailrec + - unsafe-coerce + strings: + type: registry + version: 6.0.1 + integrity: sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k= + dependencies: + - arrays + - control + - either + - enums + - foldable-traversable + - gen + - integers + - maybe + - newtype + - nonempty + - partial + - prelude + - tailrec + - tuples + - unfoldable + - unsafe-coerce + tailrec: + type: registry + version: 6.1.0 + integrity: sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk= + dependencies: + - bifunctors + - effect + - either + - identity + - maybe + - partial + - prelude + - refs + transformers: + type: registry + version: 6.0.0 + integrity: sha256-Pzw40HjthX77tdPAYzjx43LK3X5Bb7ZspYAp27wksFA= + dependencies: + - control + - distributive + - effect + - either + - exceptions + - foldable-traversable + - identity + - lazy + - maybe + - newtype + - prelude + - tailrec + - tuples + - unfoldable + tuples: + type: registry + version: 7.0.0 + integrity: sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M= + dependencies: + - control + - invariant + - prelude + type-equality: + type: registry + version: 4.0.1 + integrity: sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw= + dependencies: [] + typelevel-prelude: + type: registry + version: 7.0.0 + integrity: sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM= + dependencies: + - prelude + - type-equality + unfoldable: + type: registry + version: 6.0.0 + integrity: sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg= + dependencies: + - foldable-traversable + - maybe + - partial + - prelude + - tuples + unsafe-coerce: + type: registry + version: 6.0.0 + integrity: sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0= + dependencies: [] + web-dom: + type: registry + version: 6.0.0 + integrity: sha256-1kSKWFDI4LupdmpjK01b1MMxDFW7jvatEgPgVmCmSBQ= + dependencies: + - web-events + web-events: + type: registry + version: 4.0.0 + integrity: sha256-YDt8b6u1tzGtnWyNRodne57iO8FNSGPaTCVzBUyUn4k= + dependencies: + - datetime + - enums + - foreign + - nullable + web-file: + type: registry + version: 4.0.0 + integrity: sha256-1h5jPBkvjY71jLEdwVadXCx86/2inNoMBO//Rd3eCSU= + dependencies: + - foreign + - media-types + - web-dom + web-html: + type: registry + version: 4.1.0 + integrity: sha256-ByqS/h1/yG+hjCOnOQp7L1QpIWzQENNKB1kaHtpEhlE= + dependencies: + - js-date + - web-dom + - web-file + - web-storage + web-storage: + type: registry + version: 5.0.0 + integrity: sha256-q+6lxcnfWxus0/nDeFVtF1V+tLehZvvXQ0cduYPLksY= + dependencies: + - nullable + - web-events diff --git a/spago.yaml b/spago.yaml new file mode 100644 index 0000000..c8437a3 --- /dev/null +++ b/spago.yaml @@ -0,0 +1,22 @@ +package: + name: halogen-vdom + dependencies: + - bifunctors + - console + - effect + - exists + - foreign + - foreign-object + - maybe + - prelude + - refs + - tuples + - unsafe-coerce + - web-html + test: + main: Test.Main + dependencies: [] +workspace: + packageSet: + registry: 51.2.0 + extraPackages: {} From e9551ddb646e74108f39cb35f5520f9f95ae189d Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 14:02:05 +0800 Subject: [PATCH 02/16] Initial scaffolding for hydrateVDom Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM.purs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 90e4390..1c17018 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -5,6 +5,8 @@ module Halogen.VDom.DOM , buildElem , buildKeyed , buildWidget + , VDomHydrationSpec(..) + , hydrateVDom ) where import Prelude @@ -20,6 +22,7 @@ import Halogen.VDom.Machine (Machine, Step, Step'(..), extract, halt, mkStep, st import Halogen.VDom.Machine as Machine import Halogen.VDom.Types (ElemName(..), Namespace(..), VDom(..), runGraft) import Halogen.VDom.Util as Util +import Unsafe.Coerce (unsafeCoerce) import Web.DOM.Document (Document) as DOM import Web.DOM.Element (Element) as DOM import Web.DOM.Element as DOMElement @@ -43,6 +46,17 @@ newtype VDomSpec a w = VDomSpec , document ∷ DOM.Document } +-- | A `VDomSpec` specialized for hydration. +-- | +-- | This adds the following functions: +-- | * `hydrateWidget`, analogous to `buildWidget`. +-- | * `hydrateAttributes`, analogous to `buildAttributes`. +newtype VDomHydrationSpec a w = VDomHydrationSpec + { vdomSpec ∷ VDomSpec a w + , hydrateWidget ∷ VDomHydrationSpec a w → DOM.Node → Machine w DOM.Node + , hydrateAttributes ∷ DOM.Element → Machine a Unit + } + -- | Starts an initial `VDom` machine by providing a `VDomSpec`. -- | -- | ```purescript @@ -62,6 +76,31 @@ buildVDom spec = build Widget w → EFn.runEffectFn3 buildWidget spec build w Grafted g → EFn.runEffectFn1 build (runGraft g) +-- | Starts an initial `VDom` machine for hydration by providing a +-- | `VDomHydrationSpec` and an initial `Node`. +-- | +-- | The initial `Node` is usually the first child of the container +-- | being hydrated. +-- | +-- | ```purescript +-- | main = do +-- | machine1 ← buildVDom spec initialNode vdomTree1 +-- | machine2 ← Machine.step machine1 vdomTree2 +-- | machine3 ← Machine.step machine2 vdomTree3 +-- | ... +-- | ``` +hydrateVDom ∷ ∀ a w. VDomHydrationSpec a w → DOM.Node → VDomMachine a w +hydrateVDom _ = hydrate + where + hydrate :: DOM.Node -> VDomMachine a w + hydrate _ = EFn.mkEffectFn1 \vdom -> + case vdom of + Text _ -> unsafeCoerce unit + Elem _ _ _ _ -> unsafeCoerce unit + Keyed _ _ _ _ -> unsafeCoerce unit + Widget _ -> unsafeCoerce unit + Grafted _ -> unsafeCoerce unit + type TextState a w = { build ∷ VDomMachine a w , node ∷ DOM.Node From ed312ea276efa6b43f0c9da18f313de028ee1f94 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 14:28:42 +0800 Subject: [PATCH 03/16] Initial implementation of hydrateText Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM.purs | 19 ++++++++++++++++--- src/Halogen/VDom/Hydrate.purs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 src/Halogen/VDom/Hydrate.purs diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 1c17018..7e0cb86 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -18,6 +18,7 @@ import Data.Nullable (toNullable) import Data.Tuple (Tuple(..), fst) import Effect.Uncurried as EFn import Foreign.Object as Object +import Halogen.VDom.Hydrate as Hydrate import Halogen.VDom.Machine (Machine, Step, Step'(..), extract, halt, mkStep, step, unStep) import Halogen.VDom.Machine as Machine import Halogen.VDom.Types (ElemName(..), Namespace(..), VDom(..), runGraft) @@ -36,6 +37,8 @@ type VDomInit i a w = EFn.EffectFn1 i (VDomStep a w) type VDomBuilder i a w = EFn.EffectFn3 (VDomSpec a w) (VDomMachine a w) i (VDomStep a w) +type VDomHydrator i a w = EFn.EffectFn5 DOM.Node (VDomHydrationSpec a w) (DOM.Node -> VDomMachine a w) (VDomMachine a w) i (VDomStep a w) + type VDomBuilder4 i j k l a w = EFn.EffectFn6 (VDomSpec a w) (VDomMachine a w) i j k l (VDomStep a w) -- | Widget machines recursively reference the configured spec to potentially @@ -90,12 +93,15 @@ buildVDom spec = build -- | ... -- | ``` hydrateVDom ∷ ∀ a w. VDomHydrationSpec a w → DOM.Node → VDomMachine a w -hydrateVDom _ = hydrate +hydrateVDom hydrationSpec@(VDomHydrationSpec { vdomSpec }) = hydrate where + build :: VDomMachine a w + build = buildVDom vdomSpec + hydrate :: DOM.Node -> VDomMachine a w - hydrate _ = EFn.mkEffectFn1 \vdom -> + hydrate currentNode = EFn.mkEffectFn1 \vdom -> case vdom of - Text _ -> unsafeCoerce unit + Text s -> EFn.runEffectFn5 hydrateText currentNode hydrationSpec hydrate build s Elem _ _ _ _ -> unsafeCoerce unit Keyed _ _ _ _ -> unsafeCoerce unit Widget _ -> unsafeCoerce unit @@ -113,6 +119,13 @@ buildText = EFn.mkEffectFn3 \(VDomSpec spec) build s → do let state = { build, node, value: s } pure $ mkStep $ Step node state patchText haltText +hydrateText :: forall a w. VDomHydrator String a w +hydrateText = EFn.mkEffectFn5 \currentNode _ _ build s -> do + currentText <- Hydrate.checkIsTextNode currentNode + Hydrate.checkTextContentIsEqTo s currentText + let state = { build, node: currentNode, value: s } + pure $ mkStep $ Step currentNode state patchText haltText + patchText ∷ ∀ a w. EFn.EffectFn2 (TextState a w) (VDom a w) (VDomStep a w) patchText = EFn.mkEffectFn2 \state vdom → do let { build, node, value: value1 } = state diff --git a/src/Halogen/VDom/Hydrate.purs b/src/Halogen/VDom/Hydrate.purs new file mode 100644 index 0000000..b45f88b --- /dev/null +++ b/src/Halogen/VDom/Hydrate.purs @@ -0,0 +1,31 @@ +module Halogen.VDom.Hydrate where + +import Prelude + +import Data.Foldable (surround) +import Data.Maybe (Maybe(..)) +import Effect (Effect) +import Effect.Exception as EEx +import Partial.Unsafe (unsafePartial) +import Web.DOM.CharacterData as DOM.CharacterData +import Web.DOM.Node (Node) as DOM +import Web.DOM.Node as DOM.Node +import Web.DOM.NodeType as DOM.NodeType +import Web.DOM.Text (Text) as DOM +import Web.DOM.Text as DOM.Text + +quoteText :: String -> String +quoteText t = surround "\"" [ t ] + +checkIsTextNode :: DOM.Node -> Effect DOM.Text +checkIsTextNode node = + case DOM.Text.fromNode node of + Just text -> pure text + Nothing -> do + EEx.throwException $ EEx.error $ "Expected node to be a " <> show DOM.NodeType.TextNode <> ", but got " <> show (unsafePartial (DOM.Node.nodeType node)) + +checkTextContentIsEqTo :: String -> DOM.Text -> Effect Unit +checkTextContentIsEqTo expectedText actualText = do + textContent <- DOM.CharacterData.data_ (DOM.Text.toCharacterData actualText) + when (textContent /= expectedText) do + EEx.throwException $ EEx.error $ "Expected element text to equal to " <> quoteText expectedText <> ", but got " <> quoteText textContent From da84819ddb9202b367e2d7c451651fd3ad80fb50 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 15:15:13 +0800 Subject: [PATCH 04/16] Initial implementation of hydrateElem Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM.purs | 59 +++++++++++++- src/Halogen/VDom/Hydrate.purs | 147 +++++++++++++++++++++++++++++++++- 2 files changed, 201 insertions(+), 5 deletions(-) diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 7e0cb86..9a85405 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -13,11 +13,16 @@ import Prelude import Data.Array as Array import Data.Function.Uncurried as Fn +import Data.List (List) +import Data.List as List import Data.Maybe (Maybe(..)) import Data.Nullable (toNullable) +import Data.Traversable (traverse) import Data.Tuple (Tuple(..), fst) +import Effect (Effect) import Effect.Uncurried as EFn import Foreign.Object as Object +import Halogen.VDom.Hydrate (ElementOrTextNode) import Halogen.VDom.Hydrate as Hydrate import Halogen.VDom.Machine (Machine, Step, Step'(..), extract, halt, mkStep, step, unStep) import Halogen.VDom.Machine as Machine @@ -28,6 +33,8 @@ import Web.DOM.Document (Document) as DOM import Web.DOM.Element (Element) as DOM import Web.DOM.Element as DOMElement import Web.DOM.Node (Node) as DOM +import Web.DOM.Node as DOM.Node +import Web.DOM.NodeList as DOM.NodeList type VDomMachine a w = Machine (VDom a w) DOM.Node @@ -41,6 +48,8 @@ type VDomHydrator i a w = EFn.EffectFn5 DOM.Node (VDomHydrationSpec a w) (DOM.No type VDomBuilder4 i j k l a w = EFn.EffectFn6 (VDomSpec a w) (VDomMachine a w) i j k l (VDomStep a w) +type VDomHydrator4 i j k l a w = EFn.EffectFn8 DOM.Node (VDomHydrationSpec a w) (DOM.Node -> VDomMachine a w) (VDomMachine a w) i j k l (VDomStep a w) + -- | Widget machines recursively reference the configured spec to potentially -- | enable recursive trees of Widgets. newtype VDomSpec a w = VDomSpec @@ -102,7 +111,7 @@ hydrateVDom hydrationSpec@(VDomHydrationSpec { vdomSpec }) = hydrate hydrate currentNode = EFn.mkEffectFn1 \vdom -> case vdom of Text s -> EFn.runEffectFn5 hydrateText currentNode hydrationSpec hydrate build s - Elem _ _ _ _ -> unsafeCoerce unit + Elem ns n a ch -> EFn.runEffectFn8 hydrateElem currentNode hydrationSpec hydrate build ns n a ch Keyed _ _ _ _ -> unsafeCoerce unit Widget _ -> unsafeCoerce unit Grafted _ -> unsafeCoerce unit @@ -179,6 +188,54 @@ buildElem = EFn.mkEffectFn6 \(VDomSpec spec) build ns1 name1 as1 ch1 → do } pure $ mkStep $ Step node state patchElem haltElem +hydrateElem :: forall a w. VDomHydrator4 (Maybe Namespace) ElemName a (Array (VDom a w)) a w +hydrateElem = EFn.mkEffectFn8 \currentNode (VDomHydrationSpec { vdomSpec: VDomSpec { document }, hydrateAttributes }) hydrate build ns1 name1 as1 ch1 -> do + currentElement <- Hydrate.checkIsElementNode currentNode + Hydrate.checkTagNameIsEqualTo ns1 name1 currentElement + + currentElementChildren <- do + nodeList <- DOM.Node.childNodes currentNode + nodeArray <- DOM.NodeList.toArray nodeList + pure $ Hydrate.listToElementOrTextNode $ List.fromFoldable nodeArray + + let + toOutput :: ElementOrTextNode -> VDom a w -> { node :: DOM.Node, vdom :: VDom a w } + toOutput node vdom = { node: Hydrate.elementOrTextNodeToNode node, vdom } + + extractVdom :: VDom a w -> VDom a w + extractVdom = identity + + vdomChildren :: List (VDom a w) + vdomChildren = List.fromFoldable ch1 + + zippedChildren <- + EFn.runEffectFn6 Hydrate.zipChildrenAndSplitTextNodes + toOutput + extractVdom + document + currentNode + currentElementChildren + vdomChildren + + let + onChild :: { node :: DOM.Node, vdom :: VDom a w } -> Effect (Step (VDom a w) DOM.Node) + onChild { node, vdom } = EFn.runEffectFn1 (hydrate node) vdom + + children <- traverse onChild $ Array.fromFoldable zippedChildren + attrs <- EFn.runEffectFn1 (hydrateAttributes currentElement) as1 + + let + state = + { build + , node: currentNode + , attrs + , ns: ns1 + , name: name1 + , children + } + + pure $ mkStep $ Step currentNode state patchElem haltElem + patchElem ∷ ∀ a w. EFn.EffectFn2 (ElemState a w) (VDom a w) (VDomStep a w) patchElem = EFn.mkEffectFn2 \state vdom → do let { build, node, attrs, ns: ns1, name: name1, children: ch1 } = state diff --git a/src/Halogen/VDom/Hydrate.purs b/src/Halogen/VDom/Hydrate.purs index b45f88b..4c79c14 100644 --- a/src/Halogen/VDom/Hydrate.purs +++ b/src/Halogen/VDom/Hydrate.purs @@ -2,30 +2,169 @@ module Halogen.VDom.Hydrate where import Prelude -import Data.Foldable (surround) +import Control.Alt ((<|>)) +import Data.List (List(..), (:)) +import Data.List as List import Data.Maybe (Maybe(..)) +import Data.String as String import Effect (Effect) import Effect.Exception as EEx +import Effect.Uncurried as EFn +import Halogen.VDom.Types (ElemName(..), Namespace(..), VDom(..)) import Partial.Unsafe (unsafePartial) +import Safe.Coerce (coerce) import Web.DOM.CharacterData as DOM.CharacterData +import Web.DOM.Document (Document) as DOM +import Web.DOM.Document as DOM.Document +import Web.DOM.Element (Element) as DOM +import Web.DOM.Element as DOM.Element import Web.DOM.Node (Node) as DOM import Web.DOM.Node as DOM.Node +import Web.DOM.NodeType (NodeType) as DOM import Web.DOM.NodeType as DOM.NodeType import Web.DOM.Text (Text) as DOM import Web.DOM.Text as DOM.Text +-- Utilities + quoteText :: String -> String -quoteText t = surround "\"" [ t ] +quoteText = show + +throwExpectedNode :: forall a. DOM.NodeType -> DOM.NodeType -> Effect a +throwExpectedNode expectedNode actualNode = + EEx.throwException $ EEx.error $ "Expected node to be a " <> show expectedNode <> ", but got " <> show actualNode + +-- Text Hydration checkIsTextNode :: DOM.Node -> Effect DOM.Text checkIsTextNode node = case DOM.Text.fromNode node of Just text -> pure text - Nothing -> do - EEx.throwException $ EEx.error $ "Expected node to be a " <> show DOM.NodeType.TextNode <> ", but got " <> show (unsafePartial (DOM.Node.nodeType node)) + Nothing -> throwExpectedNode (DOM.NodeType.TextNode) (unsafePartial (DOM.Node.nodeType node)) checkTextContentIsEqTo :: String -> DOM.Text -> Effect Unit checkTextContentIsEqTo expectedText actualText = do textContent <- DOM.CharacterData.data_ (DOM.Text.toCharacterData actualText) when (textContent /= expectedText) do EEx.throwException $ EEx.error $ "Expected element text to equal to " <> quoteText expectedText <> ", but got " <> quoteText textContent + +-- Element Hydration + +checkIsElementNode :: DOM.Node -> Effect DOM.Element +checkIsElementNode node = + case DOM.Element.fromNode node of + Just element -> pure element + Nothing -> throwExpectedNode (DOM.NodeType.ElementNode) (unsafePartial (DOM.Node.nodeType node)) + +checkTagNameIsEqualTo :: Maybe Namespace -> ElemName -> DOM.Element -> Effect Unit +checkTagNameIsEqualTo namespace (ElemName elemName) element = do + let + localName :: String + localName = DOM.Element.localName element + + when (localName /= elemName) do + EEx.throwException $ EEx.error $ "Expected element localName to be " <> quoteText elemName <> ", but got " <> quoteText localName + + let + namespaceString :: Maybe String + namespaceString = coerce namespace + + namespaceURI :: Maybe String + namespaceURI = case DOM.Element.namespaceURI element of + Just "http://www.w3.org/1999/xhtml" -> Nothing + otherNamespaceURI -> otherNamespaceURI + + when (namespaceURI /= namespaceString) do + EEx.throwException $ EEx.error $ "Expected element namespaceURI to be " <> show namespaceString <> ", but got " <> show namespaceURI + +data ElementOrTextNode = ElementNode DOM.Element | TextNode DOM.Text + +elementOrTextNodeToNode :: ElementOrTextNode -> DOM.Node +elementOrTextNodeToNode referenceNode = + case referenceNode of + ElementNode element -> DOM.Element.toNode element + TextNode text -> DOM.Text.toNode text + +toElementOrTextNode :: DOM.Node -> Maybe ElementOrTextNode +toElementOrTextNode node = (DOM.Text.fromNode node <#> TextNode) <|> (DOM.Element.fromNode node <#> ElementNode) + +listToElementOrTextNode :: List DOM.Node -> List ElementOrTextNode +listToElementOrTextNode = map toElementOrTextNode >>> List.catMaybes + +-- | The idea is to prevent rerendering on the next render after hydration +-- | but because in the prerendered html all Text nodes are merged (i.e. `HH.div_ [ HH.text "foo", HH.text "bar" ]` is rendered as `
foobar
`, not `
"foo""bar"
`) +-- | and empty text nodes "" are hidden (i.e. they exist in $0.childNodes, but are not rendered), +-- | we need to split text nodes using .splitText() and insert "" nodes where it is needed +-- | +-- | Check https://jsbin.com/bukulicito/edit?html,output to see how text nodes are added to the parent +-- | The code was tested on this example https://github.com/srghma/purescript-halogen-nextjs/tree/master/examples/text-nodes +-- | +-- | Also, to undestand what's happening, you need to understand how textNode.splitText() works: +-- | 1. when $0 is '
foobar
' -> $0.childNodes[0].splitText(0) -> returns "foobar", does nothing +-- | 2. when $0 is '
foobar
' -> $0.childNodes[0].splitText(3) -> splits on "foo" and "bar", returns "bar" +-- | 3. when $0 is '
foobar
' -> $0.childNodes[0].splitText(6) -> adds new node "" after "foobar", returns "" +-- | 4. when $0 is '
foobar
' -> $0.childNodes[0].splitText(100) -> throws "Uncaught DOMException: Failed to execute 'splitText' on 'Text': The offset 100 is larger than the Text node's length." +-- | 5. when $0 is '
foobar
' -> $0.childNodes[0].splitText(-100) -> throws "Uncaught DOMException: Failed to execute 'splitText' on 'Text': The offset 4294966996 is larger than the Text node's length." +zipChildrenAndSplitTextNodes + :: forall a w vdomContainer output + . EFn.EffectFn6 + (ElementOrTextNode -> vdomContainer -> output) + (vdomContainer -> VDom a w) + DOM.Document + DOM.Node + (List ElementOrTextNode) + (List vdomContainer) + (List output) +zipChildrenAndSplitTextNodes = EFn.mkEffectFn6 \toOutput extractVdom document parent domChildren vdomContainerChildren -> + case domChildren, vdomContainerChildren of + Nil, Nil -> pure Nil + _, (vdomContainerChild : vdomContainerChildrenTail) -> + let vdomChild = extractVdom vdomContainerChild + in case domChildren, vdomChild of + -- | Expected text is "", but it wasnt rendered in dom (it is never rendered) - add the "" to the dom + _, Text "" -> do + (newChildWithEmptyText :: DOM.Text) <- DOM.Document.createTextNode "" document + + case domChildren of + -- | when DOM is `
` (no children) and vdom is `HH.div_ [HH.text ""]` - it will create append new text node + Nil -> void $ DOM.Node.appendChild (DOM.Text.toNode newChildWithEmptyText) parent + -- | when DOM is `
foo
` and vdom is `HH.div_ [HH.text "foo", HH.text ""]` - it wont touch the "foo", but should append new text node "" after "foo" + (referenceNode : _) -> do + let (referenceNode' :: DOM.Node) = elementOrTextNodeToNode referenceNode + void $ DOM.Node.insertBefore (DOM.Text.toNode newChildWithEmptyText) referenceNode' parent + + let (head :: output) = toOutput (TextNode newChildWithEmptyText) vdomContainerChild + + (tailResult :: List output) <- EFn.runEffectFn6 zipChildrenAndSplitTextNodes toOutput extractVdom document parent domChildren vdomContainerChildrenTail + + pure (head : tailResult) + -- | We have Text in dom and Text in vdom + -- | when DOM is `
foobar
` and vdom is `HH.div_ [HH.text "foobarbaz"]` - throw error (LT case) + -- | when DOM is `
foobar
` and vdom is `HH.div_ [HH.text "foobar"]` - it should just hydrate the node (EQ case) + -- | when DOM is `
foobar
` and vdom is `HH.div_ [HH.text "foo", HH.text "bar"]` - it should split "foobar" on "foo" and "bar" (GT case) + (TextNode textNode : domChildrenTail), (Text expectedText) -> do + textNodeLength <- DOM.CharacterData.length (DOM.Text.toCharacterData textNode) + + let expectedTextLength = String.length expectedText + + case compare textNodeLength expectedTextLength of + LT -> do + _ <- DOM.CharacterData.data_ (DOM.Text.toCharacterData textNode) + EEx.throwException $ EEx.error $ "[zipChildrenAndSplitTextNodes] The Text node length should not smaller then expected. Expected length = " <> show expectedTextLength <> ", actual = " <> show textNodeLength <> " (check warning above for more information)" + EQ -> do + let (head :: output) = toOutput (TextNode textNode) vdomContainerChild + tailResult <- EFn.runEffectFn6 zipChildrenAndSplitTextNodes toOutput extractVdom document parent domChildrenTail vdomContainerChildrenTail + pure (head : tailResult) + GT -> do + nextTextNode <- DOM.Text.splitText expectedTextLength textNode -- this is our "bar", and textNode is now our "foo" (but was - "foobar") + let (head :: output) = toOutput (TextNode textNode) vdomContainerChild + tailResult <- EFn.runEffectFn6 zipChildrenAndSplitTextNodes toOutput extractVdom document parent (TextNode nextTextNode : domChildrenTail) vdomContainerChildrenTail + pure (head : tailResult) + (domChild : domChildrenTail), _ -> do + let (head :: output) = toOutput domChild vdomContainerChild + tailResult <- EFn.runEffectFn6 zipChildrenAndSplitTextNodes toOutput extractVdom document parent domChildrenTail vdomContainerChildrenTail + pure (head : tailResult) + _, _ -> do + EEx.throwException $ EEx.error $ "[zipChildrenAndSplitTextNodes] Unexpected input (check warning above for more information)" + _, _ -> do + EEx.throwException $ EEx.error $ "[zipChildrenAndSplitTextNodes] Unexpected input (check warning above for more information)" From 77545af26f0f26497fee25f327d2afec9bb45c5c Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 15:17:23 +0800 Subject: [PATCH 05/16] Export hydrateText and hydrateElem --- src/Halogen/VDom/DOM.purs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 9a85405..9a145f0 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -7,6 +7,8 @@ module Halogen.VDom.DOM , buildWidget , VDomHydrationSpec(..) , hydrateVDom + , hydrateText + , hydrateElem ) where import Prelude From 6da02eead3ecdffcf83fade2488aae44732d911f Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 15:18:13 +0800 Subject: [PATCH 06/16] Implement handling for Grafted --- src/Halogen/VDom/DOM.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 9a145f0..ca622d6 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -116,7 +116,7 @@ hydrateVDom hydrationSpec@(VDomHydrationSpec { vdomSpec }) = hydrate Elem ns n a ch -> EFn.runEffectFn8 hydrateElem currentNode hydrationSpec hydrate build ns n a ch Keyed _ _ _ _ -> unsafeCoerce unit Widget _ -> unsafeCoerce unit - Grafted _ -> unsafeCoerce unit + Grafted g -> EFn.runEffectFn1 (hydrate currentNode) (runGraft g) type TextState a w = { build ∷ VDomMachine a w From 589a4296fba94170d958fb4ad31dc1745e1c1740 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 15:45:50 +0800 Subject: [PATCH 07/16] Initial implementation of hydrateKeyed Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM.purs | 57 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index ca622d6..9a77a10 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -21,6 +21,7 @@ import Data.Maybe (Maybe(..)) import Data.Nullable (toNullable) import Data.Traversable (traverse) import Data.Tuple (Tuple(..), fst) +import Data.Tuple as Tuple import Effect (Effect) import Effect.Uncurried as EFn import Foreign.Object as Object @@ -114,7 +115,7 @@ hydrateVDom hydrationSpec@(VDomHydrationSpec { vdomSpec }) = hydrate case vdom of Text s -> EFn.runEffectFn5 hydrateText currentNode hydrationSpec hydrate build s Elem ns n a ch -> EFn.runEffectFn8 hydrateElem currentNode hydrationSpec hydrate build ns n a ch - Keyed _ _ _ _ -> unsafeCoerce unit + Keyed ns n a ch -> EFn.runEffectFn8 hydrateKeyed currentNode hydrationSpec hydrate build ns n a ch Widget _ -> unsafeCoerce unit Grafted g -> EFn.runEffectFn1 (hydrate currentNode) (runGraft g) @@ -220,7 +221,7 @@ hydrateElem = EFn.mkEffectFn8 \currentNode (VDomHydrationSpec { vdomSpec: VDomSp vdomChildren let - onChild :: { node :: DOM.Node, vdom :: VDom a w } -> Effect (Step (VDom a w) DOM.Node) + onChild :: { node :: DOM.Node, vdom :: VDom a w } -> Effect (VDomStep a w) onChild { node, vdom } = EFn.runEffectFn1 (hydrate node) vdom children <- traverse onChild $ Array.fromFoldable zippedChildren @@ -325,6 +326,58 @@ buildKeyed = EFn.mkEffectFn6 \(VDomSpec spec) build ns1 name1 as1 ch1 → do } pure $ mkStep $ Step node state patchKeyed haltKeyed +hydrateKeyed :: forall a w. VDomHydrator4 (Maybe Namespace) ElemName a (Array (Tuple String (VDom a w))) a w +hydrateKeyed = EFn.mkEffectFn8 \currentNode (VDomHydrationSpec { vdomSpec: VDomSpec { document }, hydrateAttributes }) hydrate build ns1 name1 as1 ch1 -> do + currentElement <- Hydrate.checkIsElementNode currentNode + Hydrate.checkTagNameIsEqualTo ns1 name1 currentElement + + currentElementChildren <- do + nodeList <- DOM.Node.childNodes currentNode + nodeArray <- DOM.NodeList.toArray nodeList + pure $ Hydrate.listToElementOrTextNode $ List.fromFoldable nodeArray + + let + toOutput :: ElementOrTextNode -> Tuple String (VDom a w) -> { node :: DOM.Node, vdom :: VDom a w, key :: String } + toOutput node (Tuple key vdom) = { node: Hydrate.elementOrTextNodeToNode node, vdom, key } + + extractVdom :: Tuple String (VDom a w) -> VDom a w + extractVdom = Tuple.snd + + vdomChildren :: List (Tuple String (VDom a w)) + vdomChildren = List.fromFoldable ch1 + + zippedChildren <- + EFn.runEffectFn6 Hydrate.zipChildrenAndSplitTextNodes + toOutput + extractVdom + document + currentNode + currentElementChildren + vdomChildren + + let + extractKey :: { node :: DOM.Node, vdom :: VDom a w, key :: String } -> String + extractKey { key } = key + + onChild :: EFn.EffectFn3 String Int { node :: DOM.Node, vdom :: VDom a w, key :: String } (VDomStep a w) + onChild = EFn.mkEffectFn3 \_ _ { node, vdom } -> EFn.runEffectFn1 (hydrate node) vdom + + children <- EFn.runEffectFn3 Util.strMapWithIxE (Array.fromFoldable zippedChildren) extractKey onChild + attrs <- EFn.runEffectFn1 (hydrateAttributes currentElement) as1 + + let + state = + { build + , node: currentNode + , attrs + , ns: ns1 + , name: name1 + , children + , length: Array.length ch1 + } + + pure $ mkStep $ Step currentNode state patchKeyed haltKeyed + patchKeyed ∷ ∀ a w. EFn.EffectFn2 (KeyedState a w) (VDom a w) (VDomStep a w) patchKeyed = EFn.mkEffectFn2 \state vdom → do let { build, node, attrs, ns: ns1, name: name1, children: ch1, length: len1 } = state From f2142009ff5ff4b58afeba4195e947edddcdf272 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 15:53:05 +0800 Subject: [PATCH 08/16] Initial implementation of hydrateWidget Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM.purs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 9a77a10..0ddbcc9 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -9,6 +9,8 @@ module Halogen.VDom.DOM , hydrateVDom , hydrateText , hydrateElem + , hydrateKeyed + , hydrateWidget ) where import Prelude @@ -31,7 +33,6 @@ import Halogen.VDom.Machine (Machine, Step, Step'(..), extract, halt, mkStep, st import Halogen.VDom.Machine as Machine import Halogen.VDom.Types (ElemName(..), Namespace(..), VDom(..), runGraft) import Halogen.VDom.Util as Util -import Unsafe.Coerce (unsafeCoerce) import Web.DOM.Document (Document) as DOM import Web.DOM.Element (Element) as DOM import Web.DOM.Element as DOMElement @@ -116,7 +117,7 @@ hydrateVDom hydrationSpec@(VDomHydrationSpec { vdomSpec }) = hydrate Text s -> EFn.runEffectFn5 hydrateText currentNode hydrationSpec hydrate build s Elem ns n a ch -> EFn.runEffectFn8 hydrateElem currentNode hydrationSpec hydrate build ns n a ch Keyed ns n a ch -> EFn.runEffectFn8 hydrateKeyed currentNode hydrationSpec hydrate build ns n a ch - Widget _ -> unsafeCoerce unit + Widget w -> EFn.runEffectFn5 hydrateWidget currentNode hydrationSpec hydrate build w Grafted g -> EFn.runEffectFn1 (hydrate currentNode) (runGraft g) type TextState a w = @@ -447,6 +448,15 @@ buildWidget = EFn.mkEffectFn3 \(VDomSpec spec) build w → do mkStep $ Step n { build, widget: res } patchWidget haltWidget pure res' +hydrateWidget :: forall a w. VDomHydrator w a w +hydrateWidget = EFn.mkEffectFn5 \currentNode hydrationSpec@(VDomHydrationSpec { hydrateWidget: hydrateWidgetInternal }) _ build w -> do + res <- EFn.runEffectFn1 (hydrateWidgetInternal hydrationSpec currentNode) w + let + res' :: VDomStep a w + res' = res # unStep \(Step n _ _ _) -> + mkStep $ Step n { build, widget: res } patchWidget haltWidget + pure res' + patchWidget ∷ ∀ a w. EFn.EffectFn2 (WidgetState a w) (VDom a w) (VDomStep a w) patchWidget = EFn.mkEffectFn2 \state vdom → do let { build, widget } = state From 83b87728414d444865521d560621d2501edede41 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 17:26:32 +0800 Subject: [PATCH 09/16] Initial implementation of hydrateThunk Co-Authored-By: Serhii Khoma --- src/Halogen/VDom.purs | 2 +- src/Halogen/VDom/DOM.purs | 1 + src/Halogen/VDom/Thunk.purs | 25 +++++++++++++++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/Halogen/VDom.purs b/src/Halogen/VDom.purs index 797aa13..7df7a3c 100644 --- a/src/Halogen/VDom.purs +++ b/src/Halogen/VDom.purs @@ -4,6 +4,6 @@ module Halogen.VDom , module Types ) where -import Halogen.VDom.DOM (VDomSpec(..), buildVDom) as DOM +import Halogen.VDom.DOM (VDomSpec(..), VDomHydrationSpec(..), buildVDom, hydrateVDom) as DOM import Halogen.VDom.Machine (Machine, Step, Step'(..), mkStep, unStep, extract, step, halt) as Machine import Halogen.VDom.Types (VDom(..), Graft, runGraft, ElemName(..), Namespace(..)) as Types diff --git a/src/Halogen/VDom/DOM.purs b/src/Halogen/VDom/DOM.purs index 0ddbcc9..0b77fe0 100644 --- a/src/Halogen/VDom/DOM.purs +++ b/src/Halogen/VDom/DOM.purs @@ -11,6 +11,7 @@ module Halogen.VDom.DOM , hydrateElem , hydrateKeyed , hydrateWidget + , VDomMachine ) where import Prelude diff --git a/src/Halogen/VDom/Thunk.purs b/src/Halogen/VDom/Thunk.purs index 4a94040..c37741b 100644 --- a/src/Halogen/VDom/Thunk.purs +++ b/src/Halogen/VDom/Thunk.purs @@ -1,6 +1,7 @@ module Halogen.VDom.Thunk ( Thunk , buildThunk + , hydrateThunk , runThunk , hoist , mapThunk @@ -15,6 +16,7 @@ import Prelude import Data.Function.Uncurried as Fn import Effect.Uncurried as EFn import Halogen.VDom as V +import Halogen.VDom.DOM as D import Halogen.VDom.Machine as M import Halogen.VDom.Util as Util import Unsafe.Coerce (unsafeCoerce) @@ -98,11 +100,26 @@ buildThunk . (f i → V.VDom a w) → V.VDomSpec a w → V.Machine (Thunk f i) Node -buildThunk toVDom = renderThunk +buildThunk toVDom spec = mkThunk (V.buildVDom spec) toVDom + +hydrateThunk + ∷ ∀ f i a w + . (f i → V.VDom a w) + → V.VDomHydrationSpec a w + → Node + → V.Machine (Thunk f i) Node +hydrateThunk toVDom spec node = mkThunk (V.hydrateVDom spec node) toVDom + +mkThunk + ∷ ∀ f i a w + . D.VDomMachine a w + → (f i → V.VDom a w) + → V.Machine (Thunk f i) Node +mkThunk machine toVDom = renderThunk where - renderThunk ∷ V.VDomSpec a w → V.Machine (Thunk f i) Node - renderThunk spec = EFn.mkEffectFn1 \t → do - vdom ← EFn.runEffectFn1 (V.buildVDom spec) (toVDom (runThunk t)) + renderThunk ∷ V.Machine (Thunk f i) Node + renderThunk = EFn.mkEffectFn1 \t → do + vdom ← EFn.runEffectFn1 machine (toVDom (runThunk t)) pure $ M.mkStep $ M.Step (M.extract vdom) { thunk: t, vdom } patchThunk haltThunk patchThunk ∷ EFn.EffectFn2 (ThunkState f i a w) (Thunk f i) (V.Step (Thunk f i) Node) From d3f824c695d9bfea0c0b560ff34a94e6b4c37e07 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 18:24:08 +0800 Subject: [PATCH 10/16] Hoist xProp functions to prepare for reuse This puts the various xProp functions inside buildProp at the module level to prepare for code-sharing with the hydrateProp implementation. Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM/Prop.purs | 260 +++++++++++++++++++-------------- 1 file changed, 152 insertions(+), 108 deletions(-) diff --git a/src/Halogen/VDom/DOM/Prop.purs b/src/Halogen/VDom/DOM/Prop.purs index da80720..2b775a3 100644 --- a/src/Halogen/VDom/DOM/Prop.purs +++ b/src/Halogen/VDom/DOM/Prop.purs @@ -1,13 +1,4 @@ -module Halogen.VDom.DOM.Prop - ( Prop(..) - , ElemRef(..) - , PropValue - , propFromString - , propFromBoolean - , propFromInt - , propFromNumber - , buildProp - ) where +module Halogen.VDom.DOM.Prop where import Prelude @@ -19,15 +10,17 @@ import Effect (Effect) import Effect.Ref as Ref import Effect.Uncurried as EFn import Foreign (typeOf) +import Foreign.Object (Object) import Foreign.Object as Object +import Foreign.Object.ST (STObject) import Halogen.VDom as V -import Halogen.VDom.Machine (Step'(..), mkStep) +import Halogen.VDom.Machine (Step'(..), Step, mkStep) import Halogen.VDom.Types (Namespace(..)) import Halogen.VDom.Util as Util import Unsafe.Coerce (unsafeCoerce) import Web.DOM.Element (Element) as DOM import Web.Event.Event (EventType(..), Event) as DOM -import Web.Event.EventTarget (eventListener) as DOM +import Web.Event.EventTarget (EventListener, eventListener) as DOM -- | Attributes, properties, event handlers, and element lifecycles. -- | Parameterized by the type of handlers outputs. @@ -64,7 +57,20 @@ propFromInt = unsafeCoerce propFromNumber ∷ Number → PropValue propFromNumber = unsafeCoerce --- | A `Machine`` for applying attributes, properties, and event handlers. +-- Implementation + +type EmitterInputBuilder a = DOM.Event → Maybe a + +type EventListenerAndCurrentEmitterInputBuilder a = Tuple DOM.EventListener (Ref.Ref (EmitterInputBuilder a)) + +type PropState a = + { events :: Object (EventListenerAndCurrentEmitterInputBuilder a) + , props :: Object (Prop a) + , emit :: a -> Effect Unit + , el :: DOM.Element + } + +-- | A `Machine` for applying attributes, properties, and event handlers. -- | An emitter effect must be provided to respond to events. For example, -- | to allow arbitrary effects in event handlers, one could use `id`. buildProp @@ -74,109 +80,147 @@ buildProp → V.Machine (Array (Prop a)) Unit buildProp emit el = renderProp where + renderProp ∷ EFn.EffectFn1 (Array (Prop a)) (Step (Array (Prop a)) Unit) renderProp = EFn.mkEffectFn1 \ps1 → do events ← Util.newMutMap - ps1' ← EFn.runEffectFn3 Util.strMapWithIxE ps1 propToStrKey (applyProp events) + props ← EFn.runEffectFn3 Util.strMapWithIxE ps1 propToStrKey (Fn.runFn3 applyProp el emit events) let + state :: PropState a state = { events: Util.unsafeFreeze events - , props: ps1' + , props + , el + , emit } pure $ mkStep $ Step unit state patchProp haltProp - patchProp = EFn.mkEffectFn2 \state ps2 → do - events ← Util.newMutMap - let - { events: prevEvents, props: ps1 } = state - onThese = Fn.runFn2 diffProp prevEvents events - onThis = removeProp prevEvents - onThat = applyProp events - props ← EFn.runEffectFn6 Util.diffWithKeyAndIxE ps1 ps2 propToStrKey onThese onThis onThat - let - nextState = - { events: Util.unsafeFreeze events - , props - } - pure $ mkStep $ Step unit nextState patchProp haltProp - - haltProp = EFn.mkEffectFn1 \state → do - case Object.lookup "ref" state.props of - Just (Ref f) → - EFn.runEffectFn1 mbEmit (f (Removed el)) - _ → pure unit - - mbEmit = EFn.mkEffectFn1 case _ of - Just a → emit a - _ → pure unit - - applyProp events = EFn.mkEffectFn3 \_ _ v → - case v of - Attribute ns attr val → do - EFn.runEffectFn4 Util.setAttribute (toNullable ns) attr val el - pure v - Property prop val → do - EFn.runEffectFn3 setProperty prop val el - pure v - Handler (DOM.EventType ty) f → do - case Fn.runFn2 Util.unsafeGetAny ty events of - handler | Fn.runFn2 Util.unsafeHasAny ty events → do - Ref.write f (snd handler) - pure v - _ → do - ref ← Ref.new f - listener ← DOM.eventListener \ev → do - f' ← Ref.read ref - EFn.runEffectFn1 mbEmit (f' ev) - EFn.runEffectFn3 Util.pokeMutMap ty (Tuple listener ref) events - EFn.runEffectFn3 Util.addEventListener ty listener el - pure v - Ref f → do - EFn.runEffectFn1 mbEmit (f (Created el)) - pure v - - diffProp = Fn.mkFn2 \prevEvents events → EFn.mkEffectFn4 \_ _ v1 v2 → - case v1, v2 of - Attribute _ _ val1, Attribute ns2 attr2 val2 → - if val1 == val2 - then pure v2 - else do - EFn.runEffectFn4 Util.setAttribute (toNullable ns2) attr2 val2 el - pure v2 - Property _ val1, Property prop2 val2 → - case Fn.runFn2 Util.refEq val1 val2, prop2 of - true, _ → - pure v2 - _, "value" → do - let elVal = Fn.runFn2 unsafeGetProperty "value" el - if Fn.runFn2 Util.refEq elVal val2 - then pure v2 - else do - EFn.runEffectFn3 setProperty prop2 val2 el - pure v2 - _, _ → do - EFn.runEffectFn3 setProperty prop2 val2 el - pure v2 - Handler _ _, Handler (DOM.EventType ty) f → do - let - handler = Fn.runFn2 Util.unsafeLookup ty prevEvents - Ref.write f (snd handler) - EFn.runEffectFn3 Util.pokeMutMap ty handler events - pure v2 - _, _ → - pure v2 - - removeProp prevEvents = EFn.mkEffectFn2 \_ v → - case v of - Attribute ns attr _ → - EFn.runEffectFn3 Util.removeAttribute (toNullable ns) attr el - Property prop _ → - EFn.runEffectFn2 removeProperty prop el - Handler (DOM.EventType ty) _ → do - let - handler = Fn.runFn2 Util.unsafeLookup ty prevEvents - EFn.runEffectFn3 Util.removeEventListener ty (fst handler) el - Ref _ → - pure unit +patchProp :: + ∀ a + . EFn.EffectFn2 + (PropState a) + (Array (Prop a)) + (Step (Array (Prop a)) Unit) +patchProp = EFn.mkEffectFn2 \state ps2 → do + events ← Util.newMutMap + let + { events: prevEvents, props: ps1, emit, el } = state + onThese = Fn.runFn3 diffProp el prevEvents events + onThis = Fn.runFn2 removeProp el prevEvents + onThat = Fn.runFn3 applyProp el emit events + props ← EFn.runEffectFn6 Util.diffWithKeyAndIxE ps1 ps2 propToStrKey onThese onThis onThat + let + nextState :: PropState a + nextState = + { events: Util.unsafeFreeze events + , props + , el + , emit + } + pure $ mkStep $ Step unit nextState patchProp haltProp + +haltProp :: forall a. EFn.EffectFn1 (PropState a) Unit +haltProp = EFn.mkEffectFn1 \state -> do + case Object.lookup "ref" state.props of + Just (Ref f) -> + EFn.runEffectFn2 mbEmit state.emit (f (Removed state.el)) + _ -> + pure unit + +mbEmit :: forall a. EFn.EffectFn2 (a -> Effect Unit) (Maybe a) Unit +mbEmit = EFn.mkEffectFn2 \emit -> case _ of + Just a -> emit a + _ -> pure unit + +applyProp + ∷ ∀ r a + . Fn.Fn3 + DOM.Element + (a → Effect Unit) + (STObject r (EventListenerAndCurrentEmitterInputBuilder a)) + (EFn.EffectFn3 String Int (Prop a) (Prop a)) +applyProp = Fn.mkFn3 \el emit events -> EFn.mkEffectFn3 \_ _ v → + case v of + Attribute ns attr val → do + EFn.runEffectFn4 Util.setAttribute (toNullable ns) attr val el + pure v + Property prop val → do + EFn.runEffectFn3 setProperty prop val el + pure v + Handler (DOM.EventType ty) f → do + case Fn.runFn2 Util.unsafeGetAny ty events of + handler | Fn.runFn2 Util.unsafeHasAny ty events → do + Ref.write f (snd handler) + pure v + _ → do + ref ← Ref.new f + listener ← DOM.eventListener \ev → do + f' ← Ref.read ref + EFn.runEffectFn2 mbEmit emit (f' ev) + EFn.runEffectFn3 Util.pokeMutMap ty (Tuple listener ref) events + EFn.runEffectFn3 Util.addEventListener ty listener el + pure v + Ref f → do + EFn.runEffectFn2 mbEmit emit (f (Created el)) + pure v + +diffProp + ∷ ∀ r a + . Fn.Fn3 + DOM.Element + (Object.Object (EventListenerAndCurrentEmitterInputBuilder a)) + (STObject r (EventListenerAndCurrentEmitterInputBuilder a)) + (EFn.EffectFn4 String Int (Prop a) (Prop a) (Prop a)) +diffProp = Fn.mkFn3 \el prevEvents events → EFn.mkEffectFn4 \_ _ v1 v2 → + case v1, v2 of + Attribute _ _ val1, Attribute ns2 attr2 val2 → + if val1 == val2 + then pure v2 + else do + EFn.runEffectFn4 Util.setAttribute (toNullable ns2) attr2 val2 el + pure v2 + Property _ val1, Property prop2 val2 → + case Fn.runFn2 Util.refEq val1 val2, prop2 of + true, _ → + pure v2 + _, "value" → do + let elVal = Fn.runFn2 unsafeGetProperty "value" el + if Fn.runFn2 Util.refEq elVal val2 + then pure v2 + else do + EFn.runEffectFn3 setProperty prop2 val2 el + pure v2 + _, _ → do + EFn.runEffectFn3 setProperty prop2 val2 el + pure v2 + Handler _ _, Handler (DOM.EventType ty) f → do + let + handler = Fn.runFn2 Util.unsafeLookup ty prevEvents + Ref.write f (snd handler) + EFn.runEffectFn3 Util.pokeMutMap ty handler events + pure v2 + _, _ → + pure v2 + +removeProp + ∷ ∀ a + . Fn.Fn2 + DOM.Element + (Object (EventListenerAndCurrentEmitterInputBuilder a)) + (EFn.EffectFn2 String (Prop a) Unit) +removeProp = Fn.mkFn2 \el prevEvents -> EFn.mkEffectFn2 \_ v → + case v of + Attribute ns attr _ → + EFn.runEffectFn3 Util.removeAttribute (toNullable ns) attr el + Property prop _ → + EFn.runEffectFn2 removeProperty prop el + Handler (DOM.EventType ty) _ → do + let + handler = Fn.runFn2 Util.unsafeLookup ty prevEvents + EFn.runEffectFn3 Util.removeEventListener ty (fst handler) el + Ref _ → + pure unit + +-- Utilities propToStrKey ∷ ∀ i. Prop i → String propToStrKey = case _ of From 3b78e24f2f78bd8c6ab62fc5933a3df06bcaa311 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 19:03:55 +0800 Subject: [PATCH 11/16] Hoist logic to setHandler --- src/Halogen/VDom/DOM/Prop.purs | 37 ++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/Halogen/VDom/DOM/Prop.purs b/src/Halogen/VDom/DOM/Prop.purs index 2b775a3..4369128 100644 --- a/src/Halogen/VDom/DOM/Prop.purs +++ b/src/Halogen/VDom/DOM/Prop.purs @@ -146,23 +146,34 @@ applyProp = Fn.mkFn3 \el emit events -> EFn.mkEffectFn3 \_ _ v → Property prop val → do EFn.runEffectFn3 setProperty prop val el pure v - Handler (DOM.EventType ty) f → do - case Fn.runFn2 Util.unsafeGetAny ty events of - handler | Fn.runFn2 Util.unsafeHasAny ty events → do - Ref.write f (snd handler) - pure v - _ → do - ref ← Ref.new f - listener ← DOM.eventListener \ev → do - f' ← Ref.read ref - EFn.runEffectFn2 mbEmit emit (f' ev) - EFn.runEffectFn3 Util.pokeMutMap ty (Tuple listener ref) events - EFn.runEffectFn3 Util.addEventListener ty listener el - pure v + Handler ty f → do + EFn.runEffectFn5 setHandler el emit events ty f + pure v Ref f → do EFn.runEffectFn2 mbEmit emit (f (Created el)) pure v +setHandler + ∷ ∀ r a + . EFn.EffectFn5 + DOM.Element + (a -> Effect Unit) + (STObject r (EventListenerAndCurrentEmitterInputBuilder a)) + DOM.EventType + (DOM.Event -> Maybe a) + Unit +setHandler = EFn.mkEffectFn5 \el emit events (DOM.EventType ty) f → + case Fn.runFn2 Util.unsafeGetAny ty events of + handler | Fn.runFn2 Util.unsafeHasAny ty events → do + Ref.write f (snd handler) + _ → do + ref ← Ref.new f + listener ← DOM.eventListener \ev → do + f' ← Ref.read ref + EFn.runEffectFn2 mbEmit emit (f' ev) + EFn.runEffectFn3 Util.pokeMutMap ty (Tuple listener ref) events + EFn.runEffectFn3 Util.addEventListener ty listener el + diffProp ∷ ∀ r a . Fn.Fn3 From 70fa5044ae61074f332fbf736aa470a5ea7023a2 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sat, 15 Jun 2024 23:14:44 +0800 Subject: [PATCH 12/16] Initial implementation of hydrateProp Co-Authored-By: Serhii Khoma --- src/Halogen/VDom/DOM/Prop.purs | 146 ++++++++++++++++++++++++++++++++- src/Halogen/VDom/Util.js | 36 ++++++++ src/Halogen/VDom/Util.purs | 37 ++++++++- 3 files changed, 217 insertions(+), 2 deletions(-) diff --git a/src/Halogen/VDom/DOM/Prop.purs b/src/Halogen/VDom/DOM/Prop.purs index 4369128..e79ab7e 100644 --- a/src/Halogen/VDom/DOM/Prop.purs +++ b/src/Halogen/VDom/DOM/Prop.purs @@ -4,9 +4,11 @@ import Prelude import Data.Function.Uncurried as Fn import Data.Maybe (Maybe(..)) -import Data.Nullable (null, toNullable) +import Data.Nullable (null, toMaybe, toNullable) +import Data.String as String import Data.Tuple (Tuple(..), fst, snd) import Effect (Effect) +import Effect.Exception as EEx import Effect.Ref as Ref import Effect.Uncurried as EFn import Foreign (typeOf) @@ -14,8 +16,10 @@ import Foreign.Object (Object) import Foreign.Object as Object import Foreign.Object.ST (STObject) import Halogen.VDom as V +import Halogen.VDom.Hydrate (quoteText) import Halogen.VDom.Machine (Step'(..), Step, mkStep) import Halogen.VDom.Types (Namespace(..)) +import Halogen.VDom.Util (JsSet) import Halogen.VDom.Util as Util import Unsafe.Coerce (unsafeCoerce) import Web.DOM.Element (Element) as DOM @@ -94,6 +98,51 @@ buildProp emit el = renderProp } pure $ mkStep $ Step unit state patchProp haltProp +checkEmptyAttributeSet :: JsSet String -> Effect Unit +checkEmptyAttributeSet attributeSet = do + unless (Util.isEmptyAttributeSet attributeSet) do + EEx.throwException + $ EEx.error + $ "Expected element to have the attributes " + <> Util.toStringAttributeSet attributeSet + <> ", but they were not found" + +-- | A `Machine` for reconciling attributes, properties, and event handlers. +-- | An emitter effect must be provided to respond to events. For example, +-- | to allow arbitrary effects in event handlers, one could use `id`. +-- | +-- | Reconciliation combines applying attributes, properties, and event +-- | handlers with verifying the consistency of attributes and properties +-- | during the hydration pass. As such, `renderProp` and `applyProp` must +-- | be implemented accordingly. +hydrateProp + ∷ ∀ a + . (a → Effect Unit) + → DOM.Element + → V.Machine (Array (Prop a)) Unit +hydrateProp emit el = renderProp + where + renderProp = EFn.mkEffectFn1 \ps1 -> do + events <- Util.newMutMap + let + attributeSet :: JsSet String + attributeSet = Util.getAttributeSet el + props <- + EFn.runEffectFn3 Util.strMapWithIxE + ps1 + propToStrKey + (Fn.runFn4 hydrateApplyProp attributeSet el emit events) + checkEmptyAttributeSet attributeSet + let + state :: PropState a + state = + { events: Util.unsafeFreeze events + , props + , el + , emit + } + pure $ mkStep $ Step unit state patchProp haltProp + patchProp :: ∀ a . EFn.EffectFn2 @@ -153,6 +202,101 @@ applyProp = Fn.mkFn3 \el emit events -> EFn.mkEffectFn3 \_ _ v → EFn.runEffectFn2 mbEmit emit (f (Created el)) pure v +checkHasAttribute :: Maybe Namespace -> String -> String -> DOM.Element -> Effect Unit +checkHasAttribute maybeNamespace attributeName expectedValue element = do + mActualValue <- toMaybe <$> + EFn.runEffectFn3 Util.getAttribute + (toNullable maybeNamespace) + attributeName + element + case mActualValue of + Nothing -> + EEx.throwException + $ EEx.error + $ "Expected element to have an attribute " + <> quoteText (Util.fullAttributeName maybeNamespace attributeName) + <> " with value " + <> quoteText expectedValue + <> ", but it is missing" + Just actualValue -> + unless (actualValue == expectedValue) do + EEx.throwException + $ EEx.error + $ "Expected element to have an attribute " + <> quoteText (Util.fullAttributeName maybeNamespace attributeName) + <> " with value " + <> quoteText expectedValue + <> ", but it was equal to " + <> quoteText actualValue + +checkHasProp :: EFn.EffectFn3 String PropValue DOM.Element Unit +checkHasProp = EFn.mkEffectFn3 \propName expectedValue element -> do + let + actualValue :: PropValue + actualValue = Fn.runFn2 unsafeGetProperty propName element + unless (Fn.runFn2 Util.refEq actualValue expectedValue) do + EEx.throwException + $ EEx.error + $ "Expected element to have a property " + <> quoteText propName + <> " with value " + <> quoteText (Util.unsafeString expectedValue) + <> ", but it was equal to " + <> quoteText (Util.unsafeString actualValue) + +checkHasPropDelete :: EFn.EffectFn5 (JsSet String) String PropValue DOM.Element String Unit +checkHasPropDelete = EFn.mkEffectFn5 \attributeSet propName expectedValue element attributeName -> do + EFn.runEffectFn3 checkHasProp propName expectedValue element + EFn.runEffectFn2 Util.deleteAttributeSet attributeSet attributeName + +hydrateApplyProp + ∷ ∀ r a + . Fn.Fn4 + (JsSet String) + DOM.Element + (a → Effect Unit) + (STObject r (EventListenerAndCurrentEmitterInputBuilder a)) + (EFn.EffectFn3 String Int (Prop a) (Prop a)) +hydrateApplyProp = Fn.mkFn4 \attributeSet el emit events -> EFn.mkEffectFn3 \_ _ v -> + case v of + Attribute maybeNamespace attributeName attributeValue → do + checkHasAttribute maybeNamespace attributeName attributeValue el + let + fullAttributeName :: String + fullAttributeName = Util.fullAttributeName maybeNamespace attributeName + EFn.runEffectFn2 Util.deleteAttributeSet attributeSet fullAttributeName + pure v + Property propName propValue → do + case propName of + -- We need to check the attribute rather than the property since + -- the property contains the hostname, rather than just the value. + "href" -> do + checkHasAttribute Nothing "href" (Util.unsafeString propValue) el + EFn.runEffectFn2 Util.deleteAttributeSet attributeSet "href" + -- See: https://github.com/elm/virtual-dom/blob/5a5bcf48720bc7d53461b3cd42a9f19f119c5503/src/Elm/Kernel/VirtualDom.server.js#L196-L201 + "className" -> + EFn.runEffectFn5 checkHasPropDelete attributeSet propName propValue el "class" + "htmlFor" -> + EFn.runEffectFn5 checkHasPropDelete attributeSet propName propValue el "for" + "httpEquiv" -> + EFn.runEffectFn5 checkHasPropDelete attributeSet propName propValue el "http-equiv" + "acceptCharset" -> + EFn.runEffectFn5 checkHasPropDelete attributeSet propName propValue el "accept-charset" + _ -> do + EFn.runEffectFn3 checkHasProp propName propValue el + -- If a property value is a boolean and is false, the property should + -- not be rendered at all as the presence of the attribute implies a + -- truthy value. + unless (Util.unsafeIsBooleanFalse propValue) do + EFn.runEffectFn2 Util.deleteAttributeSet attributeSet $ String.toLower propName + pure v + Handler ty f → do + EFn.runEffectFn5 setHandler el emit events ty f + pure v + Ref f → do + EFn.runEffectFn2 mbEmit emit (f (Created el)) + pure v + setHandler ∷ ∀ r a . EFn.EffectFn5 diff --git a/src/Halogen/VDom/Util.js b/src/Halogen/VDom/Util.js index f59893b..4aa80a2 100644 --- a/src/Halogen/VDom/Util.js +++ b/src/Halogen/VDom/Util.js @@ -157,6 +157,14 @@ export function hasAttribute(ns, attr, el) { } } +export function getAttribute(ns, attr, el) { + if (ns != null) { + return el.getAttributeNS(ns, attr); + } else { + return el.getAttribute(attr); + } +} + export function addEventListener(ev, listener, el) { el.addEventListener(ev, listener, false); } @@ -166,3 +174,31 @@ export function removeEventListener(ev, listener, el) { } export var jsUndefined = void 0; + +export function getAttributeSet(el) { + const attributeSet = new Set(); + for (const attribute of el.attributes) { + attributeSet.add(attribute.name); + }; + return attributeSet; +} + +export function deleteAttributeSet(attributeSet, attributeName) { + attributeSet.delete(attributeName); +} + +export function isEmptyAttributeSet(attributeSet) { + return attributeSet.size === 0; +} + +export function toStringAttributeSet(attributeSet) { + return Array.from(attributeSet).map(item => `"${item}"`).join(", "); +} + +export function unsafeString(v) { + return String(v); +} + +export function unsafeIsBooleanFalse(v) { + return typeof(v) === "boolean" && !v; +} diff --git a/src/Halogen/VDom/Util.purs b/src/Halogen/VDom/Util.purs index cd4fb92..9c3bc23 100644 --- a/src/Halogen/VDom/Util.purs +++ b/src/Halogen/VDom/Util.purs @@ -25,15 +25,25 @@ module Halogen.VDom.Util , setAttribute , removeAttribute , hasAttribute + , getAttribute + , getAttributeSet + , deleteAttributeSet + , isEmptyAttributeSet + , toStringAttributeSet + , fullAttributeName , addEventListener , removeEventListener , JsUndefined , jsUndefined + , JsSet + , unsafeString + , unsafeIsBooleanFalse ) where import Prelude import Data.Function.Uncurried as Fn +import Data.Maybe (Maybe(..)) import Data.Nullable (Nullable) import Effect (Effect) import Effect.Uncurried as EFn @@ -41,7 +51,7 @@ import Foreign.Object (Object) import Foreign.Object as Object import Foreign.Object.ST (STObject) import Foreign.Object.ST as STObject -import Halogen.VDom.Types (Namespace, ElemName) +import Halogen.VDom.Types (ElemName, Namespace(..)) import Unsafe.Coerce (unsafeCoerce) import Web.DOM.Document (Document) as DOM import Web.DOM.Element (Element) as DOM @@ -161,6 +171,9 @@ foreign import removeAttribute foreign import hasAttribute ∷ EFn.EffectFn3 (Nullable Namespace) String DOM.Element Boolean +foreign import getAttribute + ∷ EFn.EffectFn3 (Nullable Namespace) String DOM.Element (Nullable String) + foreign import addEventListener ∷ EFn.EffectFn3 String DOM.EventListener DOM.Element Unit @@ -170,3 +183,25 @@ foreign import removeEventListener foreign import data JsUndefined ∷ Type foreign import jsUndefined ∷ JsUndefined + +foreign import data JsSet :: Type -> Type + +foreign import getAttributeSet :: DOM.Element -> JsSet String + +foreign import deleteAttributeSet :: EFn.EffectFn2 (JsSet String) String Unit + +foreign import isEmptyAttributeSet :: JsSet String -> Boolean + +foreign import toStringAttributeSet :: JsSet String -> String + +fullAttributeName ∷ Maybe Namespace → String → String +fullAttributeName maybeNamespace attributeName = + case maybeNamespace of + Just (Namespace namespace) -> + namespace <> ":" <> attributeName + Nothing -> + attributeName + +foreign import unsafeString :: forall a. a -> String + +foreign import unsafeIsBooleanFalse :: forall a. a -> Boolean From e8c1b676421990ade495fc1ef2b3f8261889a695 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sun, 16 Jun 2024 00:24:21 +0800 Subject: [PATCH 13/16] Add signature to renderProp --- src/Halogen/VDom/DOM/Prop.purs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Halogen/VDom/DOM/Prop.purs b/src/Halogen/VDom/DOM/Prop.purs index e79ab7e..d625fe4 100644 --- a/src/Halogen/VDom/DOM/Prop.purs +++ b/src/Halogen/VDom/DOM/Prop.purs @@ -122,6 +122,7 @@ hydrateProp → V.Machine (Array (Prop a)) Unit hydrateProp emit el = renderProp where + renderProp ∷ EFn.EffectFn1 (Array (Prop a)) (Step (Array (Prop a)) Unit) renderProp = EFn.mkEffectFn1 \ps1 -> do events <- Util.newMutMap let From d0b8fee0c5404d4323afc1c6861b5b3b45061ceb Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sun, 16 Jun 2024 19:17:33 +0800 Subject: [PATCH 14/16] Implement initial hydration tests --- package.json | 15 +- pnpm-lock.yaml | 2428 +++++++++++++++++ spago.lock | 228 ++ test-hydration/spago.yaml | 9 + test-hydration/src/Test/Hydration/Basic.purs | 68 + test-hydration/src/Test/Hydration/Driver.purs | 42 + test-hydration/src/Test/Hydration/JSDOM.js | 19 + test-hydration/src/Test/Hydration/JSDOM.purs | 12 + test-hydration/src/Test/Hydration/Render.purs | 14 + test-hydration/test/Hydration.purs | 119 + 10 files changed, 2948 insertions(+), 6 deletions(-) create mode 100644 pnpm-lock.yaml create mode 100644 test-hydration/spago.yaml create mode 100644 test-hydration/src/Test/Hydration/Basic.purs create mode 100644 test-hydration/src/Test/Hydration/Driver.purs create mode 100644 test-hydration/src/Test/Hydration/JSDOM.js create mode 100644 test-hydration/src/Test/Hydration/JSDOM.purs create mode 100644 test-hydration/src/Test/Hydration/Render.purs create mode 100644 test-hydration/test/Hydration.purs diff --git a/package.json b/package.json index 0ba0b35..dbe5cdf 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,16 @@ { "private": true, "scripts": { - "clean": "rimraf output && rimraf", - "test": "pulp build -I test -- --censor-lib --strict", - "build": "pulp build -- --censor-lib --strict" + "clean": "rimraf output", + "build": "spago build", + "test": "pnpm test:hydration", + "test:hydration": "spago test -p halogen-vdom-test-hydration" }, "devDependencies": { - "pulp": "^16.0.0-0", - "purescript-psa": "^0.8.2", - "rimraf": "^3.0.2" + "jsdom": "^24.1.0", + "purescript": "^0.15.15", + "purs-tidy": "^0.11.0", + "rimraf": "^5.0.7", + "spago": "^0.93.32" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..be1c80d --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2428 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + jsdom: + specifier: ^24.1.0 + version: 24.1.0 + purescript: + specifier: ^0.15.15 + version: 0.15.15 + purs-tidy: + specifier: ^0.11.0 + version: 0.11.0 + rimraf: + specifier: ^5.0.7 + version: 5.0.7 + spago: + specifier: ^0.93.32 + version: 0.93.32 + +packages: + + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@npmcli/fs@2.1.2': + resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + '@npmcli/move-file@2.0.1': + resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This functionality has been moved to @npmcli/fs + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + aproba@1.2.0: + resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + better-sqlite3@11.0.0: + resolution: {integrity: sha512-1NnNhmT3EZTsKtofJlMox1jkMxdedILury74PwUbQBjWgo4tL4kf7uTAjU55mgQwjdzqakSTjkf+E1imrFwjnA==} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buildcheck@0.0.6: + resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} + engines: {node: '>=10.0.0'} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + byline@5.0.0: + resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} + engines: {node: '>=0.10.0'} + + cacache@11.3.3: + resolution: {integrity: sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==} + + cacache@16.1.3: + resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + copy-concurrently@1.0.5: + resolution: {integrity: sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==} + deprecated: This package is no longer supported. + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cpu-features@0.0.10: + resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} + engines: {node: '>=10.0.0'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + cssstyle@4.0.1: + resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} + engines: {node: '>=18'} + + cyclist@1.0.2: + resolution: {integrity: sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + execa@2.1.0: + resolution: {integrity: sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==} + engines: {node: ^8.12.0 || >=9.7.0} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + figgy-pudding@3.5.2: + resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==} + deprecated: This module is no longer supported. + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + filesize@4.2.1: + resolution: {integrity: sha512-bP82Hi8VRZX/TUBKfE24iiUGsB/sfm2WUrwTQyAzQrhO3V9IhcBBNBXMyzLY5orACxRyYJ3d2HeRVX+eFv4lmA==} + engines: {node: '>= 0.4.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + flush-write-stream@1.1.1: + resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-write-stream-atomic@1.0.10: + resolution: {integrity: sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==} + deprecated: This package is no longer supported. + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fuse.js@7.0.0: + resolution: {integrity: sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==} + engines: {node: '>=10'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + engines: {node: '>= 14'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + iferr@0.1.5: + resolution: {integrity: sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + jsdom@24.1.0: + resolution: {integrity: sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^2.11.2 + peerDependenciesMeta: + canvas: + optional: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + log-symbols@3.0.0: + resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} + engines: {node: '>=8'} + + log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + make-fetch-happen@10.2.1: + resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@2.1.2: + resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mississippi@3.0.0: + resolution: {integrity: sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==} + engines: {node: '>=4.0.0'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + move-concurrently@1.0.1: + resolution: {integrity: sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==} + deprecated: This package is no longer supported. + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nan@2.20.0: + resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} + + napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-abi@3.65.0: + resolution: {integrity: sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==} + engines: {node: '>=10'} + + npm-run-path@3.1.0: + resolution: {integrity: sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==} + engines: {node: '>=8'} + + nwsapi@2.2.10: + resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + + p-finally@2.0.1: + resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} + engines: {node: '>=8'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + parallel-transform@1.2.0: + resolution: {integrity: sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prebuild-install@7.1.2: + resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} + engines: {node: '>=10'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + purescript-installer@0.3.5: + resolution: {integrity: sha512-w04BBvW4BSQlspLsZ9Bs5vtUBZqvC4bC+FizC5GUp2/rpmYvXJ0CTf79Q3MKo2A8p1ZjqbhCI+SqdTQ30UZUIQ==} + engines: {node: '>=12'} + hasBin: true + + purescript@0.15.15: + resolution: {integrity: sha512-4gwLNJa4KRiV+Wl+lyMY4MUFM6cSnIqvz7MvSTdLdvXJN2P9CrABnNbSspaokkNRFd9soWHBFDlYsAtRchqHtg==} + hasBin: true + + purs-tidy@0.11.0: + resolution: {integrity: sha512-HZ8AS6J7Ka2YVl6Gr/H5NV17TU10yGYUTxVwRd5tKuwsVdFZewXSzZ/HTpWrkhdR2gxSVk0BdnpJhyu//oRc+w==} + hasBin: true + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.7: + resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} + engines: {node: '>=14.18'} + hasBin: true + + rrweb-cssom@0.6.0: + resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} + + rrweb-cssom@0.7.1: + resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + run-queue@1.0.3: + resolution: {integrity: sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + spago@0.93.32: + resolution: {integrity: sha512-jZopAB/Bj6s2xCeTSQ3t1Q1Ymj4ZrgW4lQUAS+Ni/UajNaXR0k8lDKnJ3Jo3thioZYgCKbaKQ86ABJ7ws5igIA==} + hasBin: true + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + + spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + ssh2@1.15.0: + resolution: {integrity: sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==} + engines: {node: '>=10.16.0'} + + ssri@6.0.2: + resolution: {integrity: sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==} + + ssri@9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + stream-each@1.2.3: + resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + tar@7.2.0: + resolution: {integrity: sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==} + engines: {node: '>=18'} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + + unique-filename@2.0.1: + resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + + unique-slug@3.0.0: + resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.0.0: + resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + engines: {node: '>=18'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.17.0: + resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xhr2@0.2.1: + resolution: {integrity: sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==} + engines: {node: '>= 6'} + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + engines: {node: '>= 14'} + hasBin: true + + zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + +snapshots: + + '@gar/promisify@1.1.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@npmcli/fs@2.1.2': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.6.2 + + '@npmcli/move-file@2.0.1': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@tootallnate/once@2.0.0': {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.1: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + aproba@1.2.0: {} + + argparse@2.0.1: {} + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + astral-regex@2.0.0: {} + + asynckit@0.4.0: {} + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + better-sqlite3@11.0.0: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.2 + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bluebird@3.7.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buildcheck@0.0.6: + optional: true + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + byline@5.0.0: {} + + cacache@11.3.3: + dependencies: + bluebird: 3.7.2 + chownr: 1.1.4 + figgy-pudding: 3.5.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + lru-cache: 5.1.1 + mississippi: 3.0.0 + mkdirp: 0.5.6 + move-concurrently: 1.0.1 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 2.7.1 + ssri: 6.0.2 + unique-filename: 1.1.1 + y18n: 4.0.3 + + cacache@16.1.3: + dependencies: + '@npmcli/fs': 2.1.2 + '@npmcli/move-file': 2.0.1 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.1.0 + infer-owner: 1.0.4 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 3.0.2 + ssri: 9.0.1 + tar: 6.2.1 + unique-filename: 2.0.1 + transitivePeerDependencies: + - bluebird + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chownr@1.1.4: {} + + chownr@2.0.0: {} + + chownr@3.0.0: {} + + clean-stack@2.2.0: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + copy-concurrently@1.0.5: + dependencies: + aproba: 1.2.0 + fs-write-stream-atomic: 1.0.10 + iferr: 0.1.5 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + + core-util-is@1.0.3: {} + + cpu-features@0.0.10: + dependencies: + buildcheck: 0.0.6 + nan: 2.20.0 + optional: true + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssstyle@4.0.1: + dependencies: + rrweb-cssom: 0.6.0 + + cyclist@1.0.2: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + decimal.js@10.4.3: {} + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + detect-libc@2.0.3: {} + + duplexify@3.7.1: + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.3 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + env-paths@3.0.0: {} + + err-code@2.0.3: {} + + escape-string-regexp@1.0.5: {} + + execa@2.1.0: + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 3.1.0 + onetime: 5.1.2 + p-finally: 2.0.1 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + expand-template@2.0.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + figgy-pudding@3.5.2: {} + + file-uri-to-path@1.0.0: {} + + filesize@4.2.1: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + flush-write-stream@1.1.1: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + from2@2.3.0: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + fs-constants@1.0.0: {} + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-write-stream-atomic@1.0.10: + dependencies: + graceful-fs: 4.2.11 + iferr: 0.1.5 + imurmurhash: 0.1.4 + readable-stream: 2.3.8 + + fs.realpath@1.0.0: {} + + fuse.js@7.0.0: {} + + get-stream@5.2.0: + dependencies: + pump: 3.0.0 + + github-from-package@0.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.1: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + graceful-fs@4.2.11: {} + + has-flag@3.0.0: {} + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + http-cache-semantics@4.1.1: {} + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.4: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + iferr@0.1.5: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + infer-owner@1.0.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-lambda@1.0.1: {} + + is-number@7.0.0: {} + + is-plain-obj@2.1.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-stream@2.0.1: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jsbn@1.1.0: {} + + jsdom@24.1.0: + dependencies: + cssstyle: 4.0.1 + data-urls: 5.0.0 + decimal.js: 10.4.3 + form-data: 4.0.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.10 + parse5: 7.1.2 + rrweb-cssom: 0.7.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 + ws: 8.17.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + log-symbols@3.0.0: + dependencies: + chalk: 2.4.2 + + log-update@4.0.0: + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + + lru-cache@10.2.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@7.18.3: {} + + make-fetch-happen@10.2.1: + dependencies: + agentkeepalive: 4.5.0 + cacache: 16.1.3 + http-cache-semantics: 4.1.1 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 2.1.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 9.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + mdurl@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + mimic-response@3.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-fetch@2.1.2: + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.7 + + mississippi@3.0.0: + dependencies: + concat-stream: 1.6.2 + duplexify: 3.7.1 + end-of-stream: 1.4.4 + flush-write-stream: 1.1.1 + from2: 2.3.0 + parallel-transform: 1.2.0 + pump: 3.0.0 + pumpify: 1.5.1 + stream-each: 1.2.3 + through2: 2.0.5 + + mkdirp-classic@0.5.3: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + move-concurrently@1.0.1: + dependencies: + aproba: 1.2.0 + copy-concurrently: 1.0.5 + fs-write-stream-atomic: 1.0.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + + ms@2.1.2: {} + + ms@2.1.3: {} + + nan@2.20.0: + optional: true + + napi-build-utils@1.0.2: {} + + negotiator@0.6.3: {} + + node-abi@3.65.0: + dependencies: + semver: 7.6.2 + + npm-run-path@3.1.0: + dependencies: + path-key: 3.1.1 + + nwsapi@2.2.10: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + p-finally@2.0.1: {} + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + parallel-transform@1.2.0: + dependencies: + cyclist: 1.0.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + + picomatch@2.3.1: {} + + prebuild-install@7.1.2: + dependencies: + detect-libc: 2.0.3 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.65.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + + process-nextick-args@2.0.1: {} + + promise-inflight@1.0.1(bluebird@3.7.2): + optionalDependencies: + bluebird: 3.7.2 + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + psl@1.9.0: {} + + pump@2.0.1: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + pumpify@1.5.1: + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + purescript-installer@0.3.5: + dependencies: + byline: 5.0.0 + cacache: 11.3.3 + chalk: 2.4.2 + env-paths: 2.2.1 + execa: 2.1.0 + filesize: 4.2.1 + is-plain-obj: 2.1.0 + log-symbols: 3.0.0 + log-update: 4.0.0 + make-fetch-happen: 10.2.1 + minimist: 1.2.8 + ms: 2.1.3 + once: 1.4.0 + rimraf: 2.7.1 + semver: 7.6.2 + tar: 6.2.1 + which: 1.3.1 + zen-observable: 0.8.15 + transitivePeerDependencies: + - bluebird + - supports-color + + purescript@0.15.15: + dependencies: + purescript-installer: 0.3.5 + transitivePeerDependencies: + - bluebird + - supports-color + + purs-tidy@0.11.0: {} + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + requires-port@1.0.0: {} + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + retry@0.12.0: {} + + reusify@1.0.4: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.7: + dependencies: + glob: 10.4.1 + + rrweb-cssom@0.6.0: {} + + rrweb-cssom@0.7.1: {} + + run-applescript@7.0.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + run-queue@1.0.3: + dependencies: + aproba: 1.2.0 + + safe-buffer@5.1.2: {} + + safer-buffer@2.1.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + semver@7.6.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + smart-buffer@4.2.0: {} + + socks-proxy-agent@7.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + + socks@2.8.3: + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + + spago@0.93.32: + dependencies: + better-sqlite3: 11.0.0 + env-paths: 3.0.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + fuse.js: 7.0.0 + glob: 10.4.1 + markdown-it: 14.1.0 + micromatch: 4.0.7 + open: 10.1.0 + punycode: 2.3.1 + semver: 7.6.2 + spdx-expression-parse: 4.0.0 + ssh2: 1.15.0 + supports-color: 9.4.0 + tar: 7.2.0 + tmp: 0.2.3 + xhr2: 0.2.1 + yaml: 2.4.5 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@4.0.0: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 + + spdx-license-ids@3.0.18: {} + + sprintf-js@1.1.3: {} + + ssh2@1.15.0: + dependencies: + asn1: 0.2.6 + bcrypt-pbkdf: 1.0.2 + optionalDependencies: + cpu-features: 0.0.10 + nan: 2.20.0 + + ssri@6.0.2: + dependencies: + figgy-pudding: 3.5.2 + + ssri@9.0.1: + dependencies: + minipass: 3.3.6 + + stream-each@1.2.3: + dependencies: + end-of-stream: 1.4.4 + stream-shift: 1.0.3 + + stream-shift@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-final-newline@2.0.0: {} + + strip-json-comments@2.0.1: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@9.4.0: {} + + symbol-tree@3.2.4: {} + + tar-fs@2.1.1: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tar@7.2.0: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + tmp@0.2.3: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@5.0.0: + dependencies: + punycode: 2.3.1 + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.1.2 + + tweetnacl@0.14.5: {} + + type-fest@0.21.3: {} + + typedarray@0.0.6: {} + + uc.micro@2.1.0: {} + + unique-filename@1.1.1: + dependencies: + unique-slug: 2.0.2 + + unique-filename@2.0.1: + dependencies: + unique-slug: 3.0.0 + + unique-slug@2.0.2: + dependencies: + imurmurhash: 0.1.4 + + unique-slug@3.0.0: + dependencies: + imurmurhash: 0.1.4 + + universalify@0.2.0: {} + + universalify@2.0.1: {} + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + util-deprecate@1.0.2: {} + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@7.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.0.0: + dependencies: + tr46: 5.0.0 + webidl-conversions: 7.0.0 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@8.17.0: {} + + xhr2@0.2.1: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + xtend@4.0.2: {} + + y18n@4.0.3: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yaml@2.4.5: {} + + zen-observable@0.8.15: {} diff --git a/spago.lock b/spago.lock index a123333..975e0f5 100644 --- a/spago.lock +++ b/spago.lock @@ -70,6 +70,79 @@ workspace: - web-file - web-html - web-storage + halogen-vdom-test-hydration: + path: test-hydration + dependencies: + - halogen-vdom + - halogen-vdom-string-renderer + test_dependencies: + - spec + build_plan: + - aff + - ansi + - arrays + - avar + - bifunctors + - catenable-lists + - console + - const + - contravariant + - control + - datetime + - distributive + - effect + - either + - enums + - exceptions + - exists + - foldable-traversable + - foreign + - foreign-object + - fork + - free + - functions + - functors + - gen + - halogen-vdom + - halogen-vdom-string-renderer + - identity + - integers + - invariant + - js-date + - lazy + - lists + - maybe + - media-types + - mmorph + - newtype + - nonempty + - now + - nullable + - numbers + - ordered-collections + - orders + - parallel + - partial + - pipes + - prelude + - profunctor + - refs + - safe-coerce + - spec + - st + - strings + - tailrec + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unsafe-coerce + - web-dom + - web-events + - web-file + - web-html + - web-storage package_set: address: registry: 51.2.0 @@ -568,6 +641,36 @@ workspace: zipperarray: 2.0.0 extra_packages: {} packages: + aff: + type: registry + version: 7.1.0 + integrity: sha256-7hOC6uQO9XBAI5FD8F33ChLjFAiZVfd4BJMqlMh7TNU= + dependencies: + - arrays + - bifunctors + - control + - datetime + - effect + - either + - exceptions + - foldable-traversable + - functions + - maybe + - newtype + - parallel + - prelude + - refs + - tailrec + - transformers + - unsafe-coerce + ansi: + type: registry + version: 7.0.0 + integrity: sha256-ZMB6HD+q9CXvn9fRCmJ8dvuDrOVHcjombL3oNOerVnE= + dependencies: + - foldable-traversable + - lists + - strings arrays: type: registry version: 7.3.0 @@ -587,6 +690,17 @@ packages: - tuples - unfoldable - unsafe-coerce + avar: + type: registry + version: 5.0.0 + integrity: sha256-e7hf0x4hEpcygXP0LtvfvAQ49Bbj2aWtZT3gqM///0A= + dependencies: + - aff + - effect + - either + - exceptions + - functions + - maybe bifunctors: type: registry version: 6.0.0 @@ -597,6 +711,18 @@ packages: - newtype - prelude - tuples + catenable-lists: + type: registry + version: 7.0.0 + integrity: sha256-76vYENhwF4BWTBsjeLuErCH2jqVT4M3R1HX+4RwSftA= + dependencies: + - control + - foldable-traversable + - lists + - maybe + - prelude + - tuples + - unfoldable console: type: registry version: 6.1.0 @@ -752,6 +878,31 @@ packages: - tuples - typelevel-prelude - unfoldable + fork: + type: registry + version: 6.0.0 + integrity: sha256-X7u0SuCvFbLbzuNEKLBNuWjmcroqMqit4xEzpQwAP7E= + dependencies: + - aff + free: + type: registry + version: 7.1.0 + integrity: sha256-JAumgEsGSzJCNLD8AaFvuX7CpqS5yruCngi6yI7+V5k= + dependencies: + - catenable-lists + - control + - distributive + - either + - exists + - foldable-traversable + - invariant + - lazy + - maybe + - prelude + - tailrec + - transformers + - tuples + - unsafe-coerce functions: type: registry version: 6.0.0 @@ -791,6 +942,15 @@ packages: - tailrec - tuples - unfoldable + halogen-vdom-string-renderer: + type: registry + version: 0.5.0 + integrity: sha256-8Qxv5Ib/4ETvIa5C2WG9j39Yosc57ZOpKw5qyvGqgno= + dependencies: + - foreign + - halogen-vdom + - ordered-collections + - prelude identity: type: registry version: 6.0.0 @@ -868,6 +1028,14 @@ packages: dependencies: - newtype - prelude + mmorph: + type: registry + version: 7.0.0 + integrity: sha256-urZlZNNqGeQFe5D/ClHlR8QgGBNHTMFPtJ5S5IpflTQ= + dependencies: + - free + - functors + - transformers newtype: type: registry version: 5.0.0 @@ -931,11 +1099,39 @@ packages: dependencies: - newtype - prelude + parallel: + type: registry + version: 7.0.0 + integrity: sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o= + dependencies: + - control + - effect + - either + - foldable-traversable + - functors + - maybe + - newtype + - prelude + - profunctor + - refs + - transformers partial: type: registry version: 4.0.0 integrity: sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4= dependencies: [] + pipes: + type: registry + version: 8.0.0 + integrity: sha256-kvfqGM4cPA/wCcBHbp5psouFw5dZGvku2462x7ZBwSY= + dependencies: + - aff + - lists + - mmorph + - prelude + - tailrec + - transformers + - tuples prelude: type: registry version: 6.0.1 @@ -967,6 +1163,38 @@ packages: integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU= dependencies: - unsafe-coerce + spec: + type: registry + version: 7.6.0 + integrity: sha256-+merGdQbL9zWONbnt8S8J9afGJ59MQqGtS0qSd3yu4I= + dependencies: + - aff + - ansi + - arrays + - avar + - bifunctors + - control + - datetime + - effect + - either + - exceptions + - foldable-traversable + - fork + - identity + - integers + - lists + - maybe + - newtype + - now + - ordered-collections + - parallel + - pipes + - prelude + - refs + - strings + - tailrec + - transformers + - tuples st: type: registry version: 6.2.0 diff --git a/test-hydration/spago.yaml b/test-hydration/spago.yaml new file mode 100644 index 0000000..332f8d5 --- /dev/null +++ b/test-hydration/spago.yaml @@ -0,0 +1,9 @@ +package: + name: halogen-vdom-test-hydration + dependencies: + - halogen-vdom + - halogen-vdom-string-renderer + test: + main: Test.Hydration + dependencies: + - spec diff --git a/test-hydration/src/Test/Hydration/Basic.purs b/test-hydration/src/Test/Hydration/Basic.purs new file mode 100644 index 0000000..06d3a29 --- /dev/null +++ b/test-hydration/src/Test/Hydration/Basic.purs @@ -0,0 +1,68 @@ +module Test.Hydration.Basic where + +import Prelude + +import Data.Bifunctor (bimap) +import Data.Function.Uncurried as Fn +import Data.Maybe (Maybe(..)) +import Data.Newtype (class Newtype, un) +import Data.Tuple (Tuple) +import Halogen.VDom (VDomHydrationSpec(..), VDomSpec(..)) as V +import Halogen.VDom.DOM.Prop (Prop(..), buildProp, hydrateProp, propFromString) +import Halogen.VDom.Thunk (Thunk, buildThunk, hydrateThunk, thunk1) +import Halogen.VDom.Types (ElemName(..)) +import Halogen.VDom.Types (VDom(..)) as V +import Unsafe.Coerce (unsafeCoerce) +import Web.DOM as DOM + +attr ∷ ∀ a. String → String → Prop a +attr key value = Attribute Nothing key value + +prop ∷ ∀ a. String → String → Prop a +prop key value = Property key (propFromString value) + +infixr 1 attr as := +infixr 1 prop as .= + +type Attribute a = Array (Prop a) + +type Widget a = Thunk VDom a + +type Core a = V.VDom (Attribute a) (Widget a) + +newtype VDom a = VDom (Core a) + +instance Functor VDom where + map f (VDom vdom) = VDom (bimap (map (map f)) (map f) vdom) + +derive instance Newtype (VDom a) _ + +elem ∷ ∀ a. String → Array (Prop a) → Array (VDom a) → VDom a +elem n a c = VDom $ V.Elem Nothing (ElemName n) a (unsafeCoerce c) + +keyed ∷ ∀ a. String → Array (Prop a) → Array (Tuple String (VDom a)) → VDom a +keyed n a c = VDom $ V.Keyed Nothing (ElemName n) a (unsafeCoerce c) + +text ∷ ∀ a. String → VDom a +text a = VDom $ V.Text a + +thunk ∷ ∀ a b. (a → VDom b) → a → VDom b +thunk render val = VDom $ V.Widget $ Fn.runFn2 thunk1 render val + +type VDomSpec a = V.VDomSpec (Attribute a) (Widget a) + +mkSpec ∷ ∀ a. DOM.Document → VDomSpec a +mkSpec document = V.VDomSpec + { buildWidget: buildThunk (un VDom) + , buildAttributes: buildProp (const (pure unit)) + , document + } + +type VDomHydrationSpec a = V.VDomHydrationSpec (Attribute a) (Widget a) + +mkSpecWithHydration ∷ ∀ a. DOM.Document → VDomHydrationSpec a +mkSpecWithHydration document = V.VDomHydrationSpec + { vdomSpec: mkSpec document + , hydrateWidget: hydrateThunk (un VDom) + , hydrateAttributes: hydrateProp (const (pure unit)) + } diff --git a/test-hydration/src/Test/Hydration/Driver.purs b/test-hydration/src/Test/Hydration/Driver.purs new file mode 100644 index 0000000..78e28a4 --- /dev/null +++ b/test-hydration/src/Test/Hydration/Driver.purs @@ -0,0 +1,42 @@ +module Test.Hydration.Driver where + +import Prelude + +import Effect (Effect) +import Effect.Uncurried (runEffectFn1, runEffectFn2) +import Halogen.VDom as V +import Safe.Coerce (coerce) +import Test.Hydration.Basic as Basic +import Web.DOM as DOM + +type DriverSpec s a = + { initialState ∷ s + , render ∷ s → Basic.VDom a + } + +type DriverStep a = V.Step (Basic.Core a) DOM.Node + +type DriverPackage s a = + { machine ∷ DriverStep a + , render ∷ DriverStep a → s → Effect (DriverStep a) + } + +hydrateUI + ∷ ∀ s a. DOM.Document → DOM.Node → DriverSpec s a → Effect (DriverPackage s a) +hydrateUI document initialNode { initialState, render } = do + let + hydrationSpec ∷ Basic.VDomHydrationSpec a + hydrationSpec = Basic.mkSpecWithHydration document + + renderCore ∷ s → Basic.Core a + renderCore = coerce render + + initialRender ∷ Basic.Core a + initialRender = renderCore initialState + + renderStep ∷ DriverStep a → s → Effect (DriverStep a) + renderStep machine core = runEffectFn2 V.step machine $ renderCore core + + initialMachine ← runEffectFn1 (V.hydrateVDom hydrationSpec initialNode) + initialRender + pure { machine: initialMachine, render: renderStep } diff --git a/test-hydration/src/Test/Hydration/JSDOM.js b/test-hydration/src/Test/Hydration/JSDOM.js new file mode 100644 index 0000000..90e8dbb --- /dev/null +++ b/test-hydration/src/Test/Hydration/JSDOM.js @@ -0,0 +1,19 @@ +import { JSDOM } from "jsdom"; + +export function make(content) { + return () => { + return new JSDOM(content); + }; +}; + +export function window(jsdom) { + return () => { + return jsdom.window; + }; +}; + +export function serialize(jsdom) { + return () => { + return jsdom.serialize(); + }; +}; diff --git a/test-hydration/src/Test/Hydration/JSDOM.purs b/test-hydration/src/Test/Hydration/JSDOM.purs new file mode 100644 index 0000000..27921ed --- /dev/null +++ b/test-hydration/src/Test/Hydration/JSDOM.purs @@ -0,0 +1,12 @@ +module Test.Hydration.JSDOM where + +import Effect (Effect) +import Web.HTML.Window as HTML + +foreign import data JSDOM ∷ Type + +foreign import make ∷ String → Effect JSDOM + +foreign import window ∷ JSDOM → Effect HTML.Window + +foreign import serialize ∷ JSDOM → Effect String diff --git a/test-hydration/src/Test/Hydration/Render.purs b/test-hydration/src/Test/Hydration/Render.purs new file mode 100644 index 0000000..869549f --- /dev/null +++ b/test-hydration/src/Test/Hydration/Render.purs @@ -0,0 +1,14 @@ +module Test.Hydration.Render where + +import Halogen.VDom.DOM.StringRenderer as DSR +import Halogen.VDom.Thunk as VT +import Test.Hydration.Basic as Basic + +renderWidget ∷ ∀ a. Basic.Widget a → String +renderWidget thunk = render (VT.runThunk thunk) + +renderCore ∷ ∀ a. Basic.Core a → String +renderCore core = DSR.render renderWidget core + +render ∷ ∀ a. Basic.VDom a → String +render (Basic.VDom core) = renderCore core diff --git a/test-hydration/test/Hydration.purs b/test-hydration/test/Hydration.purs new file mode 100644 index 0000000..8988f98 --- /dev/null +++ b/test-hydration/test/Hydration.purs @@ -0,0 +1,119 @@ +module Test.Hydration where + +import Prelude + +import Control.Monad.Error.Class (class MonadThrow) +import Data.Maybe (Maybe(..)) +import Data.Tuple.Nested ((/\)) +import Effect (Effect) +import Effect.Aff (launchAff_, throwError) +import Effect.Class (class MonadEffect, liftEffect) +import Effect.Exception (Error, error) +import Test.Hydration.Basic ((.=), (:=)) +import Test.Hydration.Basic as Basic +import Test.Hydration.Driver as Driver +import Test.Hydration.JSDOM as JSDOM +import Test.Hydration.Render as Render +import Test.Spec (describe, it) +import Test.Spec.Assertions (expectError, shouldReturn) +import Test.Spec.Reporter (consoleReporter) +import Test.Spec.Runner (runSpec) +import Web.DOM (Document, Node) as DOM +import Web.DOM.Element as Element +import Web.DOM.ParentNode (QuerySelector(..), querySelector) as DOM +import Web.HTML (HTMLDocument) as DOM +import Web.HTML.HTMLDocument as HTMLDocument +import Web.HTML.Window as Window + +findInitialNode ∷ DOM.HTMLDocument → Effect DOM.Node +findInitialNode htmlDocument = do + mRootElement ← DOM.querySelector (DOM.QuerySelector "#root") + (HTMLDocument.toParentNode htmlDocument) + case mRootElement of + Just rootElement → + pure $ Element.toNode rootElement + Nothing → + throwError $ error "Cannot find #root in document." + +renderHydrate + ∷ ∀ m a + . MonadEffect m + ⇒ MonadThrow Error m + ⇒ (Boolean → Basic.VDom a) + → m Unit +renderHydrate renderFn = liftEffect do + let + serverHTML ∷ String + serverHTML = "" + <> Render.render (renderFn false) + <> "" + + jsdom ← JSDOM.make serverHTML + window ← JSDOM.window jsdom + htmlDocument ← Window.document window + initialNode ← findInitialNode htmlDocument + + let + document ∷ DOM.Document + document = HTMLDocument.toDocument htmlDocument + + driverSpec ∷ Driver.DriverSpec Boolean a + driverSpec = { initialState: true, render: renderFn } + + void $ Driver.hydrateUI document initialNode driverSpec + +main ∷ Effect Unit +main = launchAff_ $ runSpec [ consoleReporter ] do + describe "Hydration" do + it "works" do + let + general ∷ Boolean → Basic.VDom Void + general _ = + Basic.elem "div" [ "className" .= "container", "id" := "root" ] + [ Basic.elem "label" [ "htmlFor" .= "username" ] + [ Basic.text "Username" ] + , Basic.elem "input" [ "id" := "input" ] [] + , Basic.elem "a" [ "href" := "index" ] [ Basic.text "Inbox" ] + , Basic.keyed "div" [] + [ "0" /\ Basic.elem "span" [] [ Basic.text "0" ] + , "1" /\ Basic.elem "span" [] [ Basic.text "1" ] + ] + ] + renderHydrate general `shouldReturn` unit + + it "fails on mismatched properties" do + let + mismatch ∷ Boolean → Basic.VDom Void + mismatch isClient = + Basic.elem "div" [ "className" .= show isClient, "id" := "root" ] [] + expectError $ renderHydrate mismatch + + it "fails on mismatched attributes" do + let + mismatch ∷ Boolean → Basic.VDom Void + mismatch isClient = + Basic.elem "div" [ "style" := show isClient, "id" := "root" ] [] + expectError $ renderHydrate mismatch + + it "fails on mismatched elements" do + let + mismatch ∷ Boolean → Basic.VDom Void + mismatch isClient = + Basic.elem (if isClient then "div" else "span") [ "id" := "root" ] [] + expectError $ renderHydrate mismatch + + it "fails on mismatched text nodes" do + let + mismatch ∷ Boolean → Basic.VDom Void + mismatch isClient = + Basic.elem "div" [ "id" := "root" ] [ Basic.text $ show isClient ] + expectError $ renderHydrate mismatch + + it "fails on mismatched children" do + let + mismatch ∷ Boolean → Basic.VDom Void + mismatch isClient = + Basic.elem "div" [ "id" := "root" ] $ + if isClient then [] + else [ Basic.elem "span" [] [ Basic.text "Server!" ] ] + expectError $ renderHydrate mismatch From 48cb408365796837b8075d330cb81f76bd8f10f4 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sun, 16 Jun 2024 19:21:21 +0800 Subject: [PATCH 15/16] Update CI to use pnpm and spago --- .github/workflows/ci.yml | 43 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17809e8..d40c6ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [master] + branches: [master, pure/ci] pull_request: jobs: @@ -11,24 +11,41 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: purescript-contrib/setup-purescript@main + - uses: actions/setup-node@v2 with: - purescript: "unstable" + node-version: 18 - - uses: actions/setup-node@v2 + - uses: pnpm/action-setup@v4 with: - node-version: "14" + version: 9 + run_install: false - - name: Install dependencies + - name: Cache PureScript dependencies + uses: actions/cache@v2 + with: + key: ${{ runner.os }}-spago-${{ hashFiles('**/spago.yaml') }} + path: | + .spago + output + + - name: Get pnpm store directory + shell: bash run: | - npm install -g bower - npm install - bower install --production + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Cache pnpm Dependencies + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install - name: Build source - run: npm run-script build + run: pnpm build - name: Run tests - run: | - bower install - npm run-script test --if-present + run: pnpm test --silent From 265ccc5bdee570f099646b6e00867de27a7600f5 Mon Sep 17 00:00:00 2001 From: purefunctor Date: Sun, 16 Jun 2024 19:27:26 +0800 Subject: [PATCH 16/16] Remove extraneous branch --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d40c6ce..9f19dae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [master, pure/ci] + branches: [master] pull_request: jobs: