├── .gitignore ├── .prettierrc ├── README.md ├── package.json ├── pkg ├── dialect │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── ql.ts │ ├── tsconfig.json │ └── tsconfig.tsbuildinfo ├── example │ ├── index.html │ ├── package.json │ ├── src │ │ ├── data │ │ │ ├── Chinook_Sqlite.sqlite │ │ │ └── chinook.sql │ │ ├── main-old.tsx │ │ ├── main.tsx │ │ └── schema.ts │ └── tsconfig.json └── react │ ├── package.json │ ├── src │ └── index.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scratch └── scratch.md └── tsconfig-template.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .sl/ 3 | dist/ 4 | tsconfig.tsbuildinfo 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "singleQuote": false 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TreeSQL 2 | 3 | This is just a prototype of an alternate SQL syntax to pull hierarchies. 4 | 5 | 6 | 7 | 8 | A SQL that composes well and where the structure of the query matches the output of the query. 9 | 10 | ```sql 11 | SELECT { 12 | tracks: [SELECT { 13 | addedAt: tp.added_at_timestamp, 14 | trackNumber: tp.track_index, 15 | track: (SELECT { 16 | id: t.id 17 | name: t.name, 18 | durationMs: t.duration_ms, 19 | trackNumer: t.track_number, 20 | album: (SELECT a.name FROM spotify_albums AS a WHERE a.id = t.album_id), 21 | artists: [SELECT { 22 | id: art.id, 23 | name: art.name 24 | } FROM spotify_artists AS art 25 | LEFT JOIN spotify_tracks_artists AS ta 26 | ON ta.artist_id = art.id 27 | WHERE ta.track_id = t.id], 28 | } FROM spotify_tracks AS t WHERE t.id = tp.track_id) 29 | } FROM spotify_tracks_playlists as tp WHERE tp.playlist_id = p.id] 30 | } FROM spotify_playlists AS p WHERE p.id = ? 31 | ``` 32 | 33 | yields -> 34 | 35 | ```json 36 | { 37 | "tracks": [ 38 | { 39 | "addedAt": 1655612865000, 40 | "trackNumber": 1.0, 41 | "track": { 42 | "id": "spotify:track:2HdUFfnpBSxj2AsqhdrVTo", 43 | "name": "Reptilians - Chee Remix", 44 | "durationMs": 226046, 45 | "trackNumer": 0, 46 | "album": "Reptilians (Chee Remix)", 47 | "artists": [ 48 | { "id": "spotify:artist:4YWj8sohRDjL9deiuRvEEY", "name": "Noisia" }, 49 | { "id": "spotify:artist:54qqaSH6byJIb8eFWxe3Pj", "name": "Mefjus" }, 50 | { "id": "spotify:artist:6dvHFhruyFyf26otoWOXKR", "name": "Hybris" }, 51 | { "id": "spotify:artist:18fX4a2lpLLHmvJO2a5NkA", "name": "Chee" } 52 | ], 53 | } 54 | }, 55 | ... 56 | ], 57 | } 58 | ``` 59 | 60 | via -> 61 | 62 | ```sql 63 | SELECT 64 | json_object( 65 | 'tracks', 66 | ( 67 | SELECT 68 | json_group_array( 69 | json_object( 70 | 'addedAt', 71 | tp.added_at_timestamp, 72 | 'trackNumber', 73 | tp.track_index, 74 | 'track', 75 | ( 76 | SELECT 77 | json_object( 78 | 'id', 79 | t.id, 80 | 'name', 81 | t.name, 82 | 'durationMs', 83 | t.duration_ms, 84 | 'trackNumer', 85 | t.track_number, 86 | 'album', 87 | ( 88 | SELECT 89 | a.name 90 | FROM 91 | spotify_albums AS a 92 | WHERE 93 | a.id = t.album_id 94 | ), 95 | 'artists', 96 | ( 97 | SELECT 98 | json_group_array( 99 | json_object('id', art.id, 'name', art.name) 100 | ) 101 | FROM 102 | spotify_artists AS art 103 | LEFT JOIN spotify_tracks_artists AS ta ON ta.artist_id = art.id 104 | WHERE 105 | ta.track_id = t.id 106 | ) 107 | ) 108 | FROM 109 | spotify_tracks AS t 110 | WHERE 111 | t.id = tp.track_id 112 | ) 113 | ) 114 | ) 115 | FROM 116 | spotify_tracks_playlists as tp 117 | WHERE 118 | tp.playlist_id = p.id 119 | ) 120 | ) 121 | FROM 122 | spotify_playlists AS p 123 | WHERE 124 | p.id = ? 125 | 126 | ``` 127 | 128 | Added bonus -- it compiles to plain SQL. 129 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "composed-sql", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /pkg/dialect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "composed-sql", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "tsc --build" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "ohm-js": "^16.4.0" 15 | }, 16 | "devDependencies": { 17 | "typescript": "^4.9.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pkg/dialect/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ql.js"; 2 | -------------------------------------------------------------------------------- /pkg/dialect/src/ql.ts: -------------------------------------------------------------------------------- 1 | import * as ohmSynth from "ohm-js"; 2 | 3 | const ohm: typeof ohmSynth = (ohmSynth as any).default; 4 | 5 | const grammar = ohm.grammar(String.raw` 6 | CompSQL { 7 | Select 8 | = caseInsensitive<"SELECT"> "{" PropertyList "}" caseInsensitive<"FROM"> Rest -- obj 9 | | caseInsensitive<"SELECT"> AllButFrom caseInsensitive<"FROM"> Rest -- row 10 | 11 | AllButFrom = 12 | (~caseInsensitive<"FROM"> any)* 13 | 14 | SelectInner 15 | = "{" PropertyList "}" caseInsensitive<"FROM"> Rest 16 | 17 | Rest 18 | = AllButOpenOrClose "(" Rest ")" Rest -- paren 19 | | AllButOpenOrClose "[" Rest "]" Rest -- brack 20 | | AllButOpenOrClose 21 | 22 | AllButOpenOrClose = (~("]"|"["|")"|"(") any)* 23 | 24 | PropertyList 25 | = PropertyList Property ","? -- list 26 | | "" -- empty 27 | 28 | Property 29 | = propertyKey ScopedName -- primitive 30 | | propertyKey "[" caseInsensitive<"SELECT"> SelectInner "]" -- complex 31 | | propertyKey "(" Select ")" -- complexSingle 32 | 33 | propertyKey 34 | = name ":" 35 | 36 | ScopedName 37 | = (name ".")? name 38 | 39 | name 40 | = (alnum|"_")+ 41 | | "\"" (alnum|"_")+ "\"" -- quoted 42 | }`); 43 | 44 | const semantics = grammar.createSemantics(); 45 | semantics.addOperation("toSQL", { 46 | Select_obj(_select, _lBrack, propertyList, _rBrack, _from, rest) { 47 | return `SELECT json_object( 48 | ${propertyList.toSQL()} 49 | ) FROM ${rest.toSQL()}`; 50 | }, 51 | 52 | Select_row(_select, allButFrom, _from, rest) { 53 | return `SELECT ${allButFrom.toSQL()} FROM ${rest.toSQL()}`; 54 | }, 55 | 56 | AllButFrom(s) { 57 | return s.sourceString; 58 | }, 59 | 60 | _iter(...children) { 61 | return children.map((c) => c.sourceString).join(); 62 | }, 63 | 64 | SelectInner(_lBrack, propertyList, _rBrack, _from, rest) { 65 | return `json_object( 66 | ${propertyList.toSQL()} 67 | )) FROM ${rest.toSQL()}`; 68 | }, 69 | 70 | Rest(all) { 71 | return all.toSQL(); 72 | }, 73 | 74 | Rest_brack(all, _lParen, rest, _rParen, rest2) { 75 | return `${all.toSQL()} (${rest.toSQL()}) ${rest2.toSQL()}`; 76 | }, 77 | 78 | Rest_paren(all, _lParen, rest, _rParen, rest2) { 79 | return `${all.toSQL()} (${rest.toSQL()}) ${rest2.toSQL()}`; 80 | }, 81 | 82 | AllButOpenOrClose(s) { 83 | return s.sourceString; 84 | }, 85 | 86 | PropertyList_list(propList, prop, _maybeComma) { 87 | return [...propList.toSQL(), prop.toSQL()]; 88 | }, 89 | 90 | PropertyList_empty(_) { 91 | return []; 92 | }, 93 | 94 | Property_primitive(key, scopedName) { 95 | return `'${key.toSQL()}', ${scopedName.toSQL()}`; 96 | }, 97 | 98 | Property_complex(key, _lParen, _select, selectInner, _rParen) { 99 | return `'${key.toSQL()}', (SELECT json_group_array(${selectInner.toSQL()})`; 100 | }, 101 | 102 | Property_complexSingle(key, _lParen, select, _rParen) { 103 | return `'${key.toSQL()}', (${select.toSQL()})`; 104 | }, 105 | 106 | propertyKey(name, _colon) { 107 | return name.toSQL(); 108 | }, 109 | 110 | ScopedName(n1, _dot, n2) { 111 | if (n1) { 112 | return n1.toSQL() + "." + n2.toSQL(); 113 | } 114 | 115 | return n2.toSQL(); 116 | }, 117 | 118 | name(name) { 119 | return name.sourceString; 120 | }, 121 | }); 122 | 123 | export function parse(str: string): string { 124 | const matchResult = grammar.match(str); 125 | if (matchResult.failed()) { 126 | throw new Error(matchResult.message); 127 | } 128 | 129 | const adapter = semantics(matchResult); 130 | return adapter.toSQL(); 131 | } 132 | 133 | export function sql(strings: TemplateStringsArray, ...values: any[]) { 134 | return String.raw({ raw: strings }, ...values); 135 | } 136 | -------------------------------------------------------------------------------- /pkg/dialect/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-template.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/", 5 | "rootDir": "./src" 6 | }, 7 | "include": ["./src/"], 8 | "references": [{ }] 9 | } 10 | -------------------------------------------------------------------------------- /pkg/dialect/tsconfig.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"program":{"fileNames":["../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.3/node_modules/typescript/lib/lib.esnext.full.d.ts","../../node_modules/.pnpm/ohm-js@16.4.0/node_modules/ohm-js/index.d.ts","./src/ql.ts","./src/index.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18","1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9","746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f","d11a03592451da2d1065e09e61f4e2a9bf68f780f4f6623c18b57816a9679d17","aea179452def8a6152f98f63b191b84e7cbd69b0e248c91e61fb2e52328abe8c",{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"f3d4da15233e593eacb3965cde7960f3fddf5878528d882bcedd5cbaba0193c7","affectsGlobalScope":true},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true},{"version":"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87","affectsGlobalScope":true},{"version":"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe","affectsGlobalScope":true},{"version":"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7","affectsGlobalScope":true},{"version":"34c839eaaa6d78c8674ae2c37af2236dee6831b13db7b4ef4df3ec889a04d4f2","affectsGlobalScope":true},{"version":"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed","affectsGlobalScope":true},{"version":"ab7d58e6161a550ff92e5aff755dc37fe896245348332cd5f1e1203479fe0ed1","affectsGlobalScope":true},{"version":"6bda95ea27a59a276e46043b7065b55bd4b316c25e70e29b572958fa77565d43","affectsGlobalScope":true},{"version":"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66","affectsGlobalScope":true},{"version":"a4da0551fd39b90ca7ce5f68fb55d4dc0c1396d589b612e1902f68ee090aaada","affectsGlobalScope":true},{"version":"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},"d96fa8a56871904776165ceb8e00bd56127e1a017bb2664cae76223b5f815141","961aba47c1fa469e6798d7993cbed49b38e739fdc37eb125785b88c676fc0f38",{"version":"97d8895a32f190506bbff48eb7d47675203c829a396d5bdc2ca7257f265c1e60","signature":"7ace1722754e0e4533f164ef618c8fa73877c694d1e795884384559d3ac3d1db"},"2d9e2d09d0546647a65007b5dd90521fd3050f6760b635dcede1bfab4b96f5e5"],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":99,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":true,"strictNullChecks":true,"target":99},"fileIdsList":[[61],[60]],"referencedMap":[[62,1],[61,2]],"exportedModulesMap":[[62,1]],"semanticDiagnosticsPerFile":[60,11,12,16,15,2,17,18,19,20,21,22,23,24,3,4,28,25,26,27,29,30,31,5,32,33,34,35,6,39,36,37,38,40,7,41,46,47,42,43,44,45,8,51,48,49,50,52,9,53,54,55,56,57,1,10,59,58,14,13,62,61],"latestChangedDtsFile":"./dist/ql.d.ts"},"version":"4.9.3"} -------------------------------------------------------------------------------- /pkg/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | composed sql demo 8 | 9 | 10 | 11 | 12 | 13 | 14 |
Populating database
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /pkg/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "tsc": "tsc --noEmit", 9 | "start": "vite", 10 | "build": "vite build" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "@vlcn.io/rx-tbl": "^0.3.0", 17 | "@vlcn.io/wa-crsqlite": "^0.4.1", 18 | "composed-sql": "workspace:*", 19 | "composed-sql-react": "workspace:*", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0" 22 | }, 23 | "devDependencies": { 24 | "@types/react": "^18.0.25", 25 | "@types/react-dom": "^18.0.9", 26 | "typescript": "^4.9.3", 27 | "typescript-plugin-css-modules": "^3.4.0", 28 | "vite": "^3.2.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/example/src/data/Chinook_Sqlite.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tantaman/TreeSQL/3414d44a9a861d603ed7884ca6bd531617a68537/pkg/example/src/data/Chinook_Sqlite.sqlite -------------------------------------------------------------------------------- /pkg/example/src/main-old.tsx: -------------------------------------------------------------------------------- 1 | import { sql } from "composed-sql"; 2 | import sqliteWasm from "@vlcn.io/wa-crsqlite"; 3 | 4 | const sqlite = await sqliteWasm(); 5 | const db1 = await sqlite.open(":memory:"); 6 | 7 | await db1.execMany([ 8 | `CREATE TABLE deck (id primary key, name);`, 9 | `CREATE TABLE slide (id primary key, "order", deck_id);`, 10 | `CREATE TABLE component (id primary key, text, slide_id);`, 11 | `CREATE INDEX slide_deck ON slide (deck_id);`, 12 | `CREATE INDEX comp_slide ON component (slide_id);`, 13 | ]); 14 | 15 | await db1.execMany([ 16 | `INSERT INTO deck VALUES (1, 'first');`, 17 | `INSERT INTO slide VALUES (1, 0, 1);`, 18 | `INSERT INTO slide VALUES (2, 1, 1);`, 19 | `INSERT INTO component VALUES (1, 'some text', 1);`, 20 | `INSERT INTO component VALUES (2, 'some other text', 1);`, 21 | `INSERT INTO component VALUES (3, 'some more text', 1);`, 22 | ]); 23 | 24 | const r = await db1.execA(sql` 25 | SELECT { 26 | id: deck.id, 27 | slides: [SELECT { 28 | id: slide.id, 29 | order: slide."order", 30 | components: [SELECT { 31 | id: component.id, 32 | text: component.text 33 | } FROM component WHERE component.slide_id = slide.id] 34 | } FROM slide WHERE slide.deck_id = deck.id], 35 | } FROM deck`); 36 | 37 | console.log(r.map((s: any) => JSON.parse(s))); 38 | 39 | const id = "1"; 40 | const trackArtists = /*sql*/ `(SELECT { 41 | id: art.id, 42 | name: art.name 43 | } FROM spotify_arists AS art 44 | LEFT JOIN spotify_tracks_artists AS ta 45 | ON ta.artist_id = art.id 46 | WHERE ta.track_id = t.id)`; 47 | 48 | // note: 49 | // we can hoist sub-selects as fragments 50 | // and make them reactive on the component that uses them. 51 | // e.g., like Relay `useFragment` hooks. 52 | const top = sql` 53 | SELECT { 54 | tracks: [SELECT { 55 | addedAt: tp.added_at_timestamp, 56 | trackNumber: tp.track_index, 57 | track: (SELECT { 58 | id: t.id, 59 | name: t.name, 60 | durationMs: t.duration_ms, 61 | trackNumer: t.track_number, 62 | album: (SELECT a.name FROM spotify_albums AS a WHERE a.id = t.album_id), 63 | artists: [SELECT { 64 | id: art.id, 65 | name: art.name 66 | } FROM spotify_artists AS art 67 | LEFT JOIN spotify_tracks_artists AS ta 68 | ON ta.artist_id = art.id 69 | WHERE ta.track_id = t.id], 70 | } FROM spotify_tracks AS t WHERE t.id = tp.track_id) 71 | } FROM spotify_tracks_playlists as tp WHERE tp.playlist_id = p.id] 72 | } FROM spotify_playlists AS p WHERE p.id = ? 73 | `; 74 | 75 | // We could be more succicnt by: 76 | // 1. omitting select 77 | // 2. allow omitting alias names 78 | // 3. omit from?? and put table name first? 79 | // but 1 & 3 may make too unrecognizable from sql 80 | 81 | let fragCount = 0; 82 | // just allow literal and bind params? no interp? 83 | function frag(strings: TemplateStringsArray, ...values: any[]): Frag { 84 | return { 85 | count: ++fragCount, 86 | // TODO: should shadow fields 87 | // or should de-dupe fields in the final composed query 88 | embedding: String.raw({ raw: strings }, ...values), 89 | standalone: "the embedding but as standalone", 90 | // ^- field only frags have no standalone? 91 | // the _simplest_ first pass would be to 92 | // not do any splitting and literally 93 | // re-run the whole composed query then _diff_ 94 | // by frag. 95 | // - data comes in 96 | // - we mutate frag refs on props (yes, mutate a prop) 97 | // - useFrag listens to those refs 98 | // - useFrag diffs 99 | // - if different, set state 100 | // 101 | // can we rm react then? since react 102 | // will dom diff too 103 | // but if we data diff, why dom diff? 104 | // we are pretty sure what'll be touched. 105 | // 106 | // put db in worker for this approach? 107 | }; 108 | } 109 | 110 | type Frag = { 111 | embedding: string; 112 | standalone: string; 113 | count: number; 114 | }; 115 | 116 | function include(frag: Frag) { 117 | return frag.embedding; 118 | } 119 | 120 | const albumFrag = frag` 121 | album: (SELECT a.name FROM spotify_albums AS a WHERE a.id = t.album_id), 122 | `; // more ergonimic? 123 | // ^-- gets re-written with frag id? 124 | // useFrag(albumFrag, data.track); 125 | 126 | // can only frag on fields 127 | function useFrag(fragment: Frag, data: T) { 128 | // if there's a select we can hoist it separately? 129 | // and bind to it separately? 130 | // 1. run the query 131 | // 2. subscribe to it 132 | // 3. pull semantics from it 133 | } 134 | 135 | `spotify_playlists: [{ 136 | tracks: [spotify_tracks_playlists { 137 | addedAt, 138 | trackNumber, 139 | track: (spotify_tracks { 140 | 141 | }) 142 | }] 143 | }]`; 144 | 145 | console.log(top); 146 | -------------------------------------------------------------------------------- /pkg/example/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import { sql, parse } from "composed-sql"; 4 | // @ts-ignore 5 | import wasmUrl from "@vlcn.io/wa-crsqlite/wa-sqlite-async.wasm?url"; 6 | import sqliteWasm from "@vlcn.io/wa-crsqlite"; 7 | import tblrx from "@vlcn.io/rx-tbl"; 8 | import { createSchema } from "./schema"; 9 | import { Ctx, useQueryA, useQueryJ } from "composed-sql-react"; 10 | 11 | async function main() { 12 | const sqlite = await sqliteWasm((file) => wasmUrl); 13 | 14 | const db = await sqlite.open(":memory:"); 15 | (window as any).db = db; 16 | const rx = await tblrx(db); 17 | 18 | await createSchema(db); 19 | 20 | const root = createRoot(document.getElementById("content")!); 21 | root.render( 22 | 28 | ); 29 | } 30 | 31 | function App({ ctx }: { ctx: Ctx }) { 32 | return ( 33 |
34 | 35 |
36 | ); 37 | } 38 | 39 | const artistsFrag = sql`[SELECT { 40 | id: Artist.ArtistId, 41 | name: Artist.Name 42 | } FROM Artist 43 | JOIN Album 44 | ON Album.ArtistId = Artist.ArtistId 45 | WHERE Album.AlbumId = t.AlbumId]`; 46 | 47 | type Artist = { id: string; name: string }; 48 | function ArtistsCell({ artists }: { artists: Artist[] }) {} 49 | 50 | const trackFrag = sql` 51 | id: t.TrackId, 52 | name: t.Name, 53 | album: (SELECT Album.Title FROM Album WHERE Album.AlbumId = t.AlbumId), 54 | duration: t.Milliseconds, 55 | artists: ${artistsFrag} 56 | `; 57 | 58 | type Track = { 59 | id: string; 60 | name: string; 61 | album: string; 62 | duration: number; 63 | artists: Artist[]; 64 | }; 65 | function Track({ track }: { track: Track }) {} 66 | 67 | // TODO: need a better way to impose 68 | // limits on json_group_array rather than selecting 69 | // from limited sub-select. 70 | // We should extend the grammar to parse out limits and offsets 71 | // and re-roll the query in those cases 72 | const playlistQuery = sql` 73 | SELECT { 74 | id: p.PlaylistId, 75 | name: p.Name, 76 | tracks: [SELECT { 77 | ${trackFrag} 78 | } FROM (SELECT * FROM PlaylistTrack AS pt 79 | JOIN Track ON Track.TrackId = pt.TrackId 80 | WHERE pt.PlaylistId = p.PlaylistId 81 | LIMIT 200) as t] 82 | } FROM Playlist AS p WHERE p.PlaylistId = ?`; 83 | type Playlist = { 84 | tracks: Track[]; 85 | }; 86 | 87 | console.log(parse(playlistQuery)); 88 | function Playlist({ ctx, playlistId }: { ctx: Ctx; playlistId: number }) { 89 | const data = useQueryJ( 90 | ctx, 91 | ["Playlist", "Album", "Track", "Artist", "PlaylistTrack"], 92 | playlistQuery, 93 | [playlistId] 94 | ); 95 | console.log(data); 96 | return
playlist
; 97 | } 98 | 99 | main(); 100 | -------------------------------------------------------------------------------- /pkg/example/src/schema.ts: -------------------------------------------------------------------------------- 1 | import { DB } from "@vlcn.io/wa-crsqlite"; 2 | // @ts-ignore 3 | import dataset from "./data/chinook.sql?raw"; 4 | 5 | // export async function createSchema(db: DB) { 6 | // await db.execMany([ 7 | // "CREATE TABLE albums (id primary key, name, colors_string);", 8 | // "CREATE TABLE tracks (id primary key, name, album_id, track_number, duration_ms);", 9 | // "CREATE TABLE artists (id primary key, name, colors_string);", 10 | // "CREATE TABLE tracks_artists (track_id, artist_id, primary key (track_id, artist_id));", 11 | // "CREATE TABLE tracks_playlists (track_id, playlist_id, track_index, added_at_timestamp, primary key (playlist_id, track_id));", 12 | // "CREATE TABLE playlists (id primary key, name, description, collaborative, owner_id, owner_name, colors_string);", 13 | 14 | // "CREATE INDEX track_to_playlists ON tracks_playlists (playlist_id);", 15 | // "CREATE INDEX artist_to_tracks ON track_artists (artist_id);", 16 | // ]); 17 | // } 18 | 19 | export function createSchema(db: DB) { 20 | return db.exec(dataset); 21 | } 22 | -------------------------------------------------------------------------------- /pkg/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", // path to output directory 4 | "sourceMap": true, // allow sourcemap support 5 | "strictNullChecks": true, // enable strict null checks as a best practice 6 | "module": "esnext", // specify module code generation 7 | "target": "esnext", // specify ECMAScript target version 8 | "moduleResolution": "node", 9 | "rootDir": "./", 10 | "allowJs": true, 11 | "jsx": "react", 12 | "strict": true, 13 | "skipLibCheck": true, 14 | "allowSyntheticDefaultImports": true, 15 | "importHelpers": true, 16 | "resolveJsonModule": true, 17 | "plugins": [{ "name": "typescript-plugin-css-modules" }] 18 | }, 19 | "include": ["./src/"], 20 | "references": [{ "path": "../dialect" }, { "path": "../react" }] 21 | } 22 | -------------------------------------------------------------------------------- /pkg/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "composed-sql-react", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "tsc --build" 9 | }, 10 | "peerDependencies": { 11 | "composed-sql": "workspace:*", 12 | "react": "^18.2.0" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "devDependencies": { 18 | "@types/react": "^18.0.25", 19 | "composed-sql": "workspace:*", 20 | "react": "^18.2.0", 21 | "typescript": "^4.9.3" 22 | }, 23 | "dependencies": { 24 | "@vlcn.io/rx-tbl": "^0.3.0", 25 | "@vlcn.io/xplat-api": "^0.3.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pkg/react/src/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { DBAsync, StmtAsync } from "@vlcn.io/xplat-api"; 3 | import tblrx from "@vlcn.io/rx-tbl"; 4 | import { parse } from "composed-sql"; 5 | 6 | export type Ctx = { 7 | db: DBAsync; 8 | rx: Awaited>; 9 | }; 10 | 11 | type QueryData = { 12 | loading: boolean; 13 | error?: Error; 14 | data: M; 15 | }; 16 | 17 | type SQL = string; 18 | export type Query = 19 | | [Ctx, T[], SQL, any[]] 20 | | [Ctx, T[], SQL, any[], (x: R[]) => M]; 21 | 22 | // TODO: `useQuery` should prepare a statement 23 | function useQueryImpl( 24 | [ctx, tables, query, bindings, postProcess]: Query, 25 | mode: "o" | "a" | "j" 26 | ): QueryData { 27 | const [state, setState] = useState>({ 28 | data: postProcess != null ? postProcess([]) : ([] as any), 29 | loading: true, 30 | }); 31 | // TODO: counting / logging to ensure this runs as often as expected 32 | useEffect(() => { 33 | let isMounted = true; 34 | 35 | let compiledQuery = query; 36 | if (mode == "j") { 37 | compiledQuery = parse(query); 38 | } 39 | 40 | const runQuery = (changedTbls: Set | null, stmt: StmtAsync) => { 41 | if (!isMounted) { 42 | return; 43 | } 44 | 45 | if (changedTbls != null) { 46 | if (!tables.some((t) => changedTbls.has(t))) { 47 | return; 48 | } 49 | } 50 | 51 | stmt.all(...bindings).then((data) => { 52 | if (!isMounted) { 53 | return; 54 | } 55 | try { 56 | setState({ 57 | data: 58 | postProcess != null 59 | ? // TODO: postProcess should work on full dataset for more flexibility 60 | postProcess((data as R[]) || []) 61 | : (data as M), 62 | loading: false, 63 | }); 64 | } catch (e) { 65 | console.error("Failed post-processing data for query: " + query); 66 | throw e; 67 | } 68 | }); 69 | }; 70 | 71 | let disposer = () => {}; 72 | let stmtOuter: StmtAsync | null = null; 73 | ctx.db.prepare(compiledQuery).then((stmt) => { 74 | if (mode === "a" || mode == "j") { 75 | stmt.raw(true); 76 | } 77 | if (!isMounted) { 78 | stmt.finalize(); 79 | return; 80 | } 81 | stmtOuter = stmt; 82 | disposer = ctx.rx.on((tbls) => runQuery(tbls, stmt)); 83 | 84 | // initial kickoff to get initial data. 85 | runQuery(null, stmt); 86 | }); 87 | 88 | return () => { 89 | isMounted = false; 90 | stmtOuter?.finalize(); 91 | disposer(); 92 | }; 93 | }, [query, ...(bindings || [])]); 94 | 95 | return state; 96 | } 97 | 98 | export function useQuery( 99 | q: Query 100 | ): QueryData { 101 | return useQueryImpl(q, "o"); 102 | } 103 | 104 | export function useQueryJ( 105 | ctx: Ctx, 106 | tables: T[], 107 | query: string, 108 | bindings: any[] = [] 109 | ) { 110 | return useQueryImpl( 111 | [ 112 | ctx, 113 | tables, 114 | query, 115 | bindings, 116 | (data: any[]) => { 117 | if (data.length == 1) { 118 | return JSON.parse(data[0]); 119 | } 120 | return data.map((d) => JSON.parse(d)); 121 | }, 122 | ], 123 | "j" 124 | ); 125 | } 126 | 127 | export function useQueryA( 128 | q: Query 129 | ): QueryData { 130 | return useQueryImpl(q, "a"); 131 | } 132 | 133 | export function first(data: T[]): T | undefined { 134 | if (!data) { 135 | return undefined; 136 | } 137 | return data[0]; 138 | } 139 | 140 | export function firstPick(data: any[]): T | undefined { 141 | const d = data[0]; 142 | if (d == null) { 143 | return undefined; 144 | } 145 | 146 | return d[Object.keys(d)[0]]; 147 | } 148 | 149 | export function pick0(data: T[]): T[0][] { 150 | return data.map((d) => d[0]); 151 | } 152 | 153 | export function useBind(keys: T[], d?: D) {} 154 | -------------------------------------------------------------------------------- /pkg/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-template.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/", 5 | "rootDir": "./src" 6 | }, 7 | "include": ["./src/"], 8 | "references": [{ "path": "../dialect" }] 9 | } 10 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | importers: 4 | 5 | .: 6 | specifiers: {} 7 | 8 | pkg/dialect: 9 | specifiers: 10 | ohm-js: ^16.4.0 11 | typescript: ^4.9.3 12 | dependencies: 13 | ohm-js: 16.4.0 14 | devDependencies: 15 | typescript: 4.9.3 16 | 17 | pkg/example: 18 | specifiers: 19 | '@types/react': ^18.0.25 20 | '@types/react-dom': ^18.0.9 21 | '@vlcn.io/rx-tbl': ^0.3.0 22 | '@vlcn.io/wa-crsqlite': ^0.4.1 23 | composed-sql: workspace:* 24 | composed-sql-react: workspace:* 25 | react: ^18.2.0 26 | react-dom: ^18.2.0 27 | typescript: ^4.9.3 28 | typescript-plugin-css-modules: ^3.4.0 29 | vite: ^3.2.4 30 | dependencies: 31 | '@vlcn.io/rx-tbl': 0.3.0 32 | '@vlcn.io/wa-crsqlite': 0.4.1 33 | composed-sql: link:../dialect 34 | composed-sql-react: link:../react 35 | react: 18.2.0 36 | react-dom: 18.2.0_react@18.2.0 37 | devDependencies: 38 | '@types/react': 18.0.25 39 | '@types/react-dom': 18.0.9 40 | typescript: 4.9.3 41 | typescript-plugin-css-modules: 3.4.0_typescript@4.9.3 42 | vite: 3.2.4 43 | 44 | pkg/react: 45 | specifiers: 46 | '@types/react': ^18.0.25 47 | '@vlcn.io/rx-tbl': ^0.3.0 48 | '@vlcn.io/xplat-api': ^0.3.0 49 | composed-sql: workspace:* 50 | react: ^18.2.0 51 | typescript: ^4.9.3 52 | dependencies: 53 | '@vlcn.io/rx-tbl': 0.3.0 54 | '@vlcn.io/xplat-api': 0.3.0 55 | devDependencies: 56 | '@types/react': 18.0.25 57 | composed-sql: link:../dialect 58 | react: 18.2.0 59 | typescript: 4.9.3 60 | 61 | packages: 62 | 63 | /@esbuild/android-arm/0.15.16: 64 | resolution: {integrity: sha512-nyB6CH++2mSgx3GbnrJsZSxzne5K0HMyNIWafDHqYy7IwxFc4fd/CgHVZXr8Eh+Q3KbIAcAe3vGyqIPhGblvMQ==} 65 | engines: {node: '>=12'} 66 | cpu: [arm] 67 | os: [android] 68 | requiresBuild: true 69 | dev: true 70 | optional: true 71 | 72 | /@esbuild/linux-loong64/0.15.16: 73 | resolution: {integrity: sha512-SDLfP1uoB0HZ14CdVYgagllgrG7Mdxhkt4jDJOKl/MldKrkQ6vDJMZKl2+5XsEY/Lzz37fjgLQoJBGuAw/x8kQ==} 74 | engines: {node: '>=12'} 75 | cpu: [loong64] 76 | os: [linux] 77 | requiresBuild: true 78 | dev: true 79 | optional: true 80 | 81 | /@types/json5/0.0.29: 82 | resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} 83 | dev: true 84 | 85 | /@types/prop-types/15.7.5: 86 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 87 | dev: true 88 | 89 | /@types/react-dom/18.0.9: 90 | resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} 91 | dependencies: 92 | '@types/react': 18.0.25 93 | dev: true 94 | 95 | /@types/react/18.0.25: 96 | resolution: {integrity: sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==} 97 | dependencies: 98 | '@types/prop-types': 15.7.5 99 | '@types/scheduler': 0.16.2 100 | csstype: 3.1.1 101 | dev: true 102 | 103 | /@types/scheduler/0.16.2: 104 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 105 | dev: true 106 | 107 | /@vlcn.io/rx-tbl/0.3.0: 108 | resolution: {integrity: sha512-qIH7fusMB21aS0LV2A8lAwM8dToKZsi4JWaDIIXAsu9Y0caOp8U19RLNJ2pbBzVh4RtUjBueTr0fAHE5nU1mlw==} 109 | dependencies: 110 | '@vlcn.io/xplat-api': 0.3.0 111 | dev: false 112 | 113 | /@vlcn.io/wa-crsqlite/0.4.1: 114 | resolution: {integrity: sha512-7D7kiQTcYv0nCGbe6d0t+yp7UMvYx/n8DZtxgHbOgwpth7ktq/vpwBn5LZVtlia20PFJZtZ2a3BC19P6VawWyQ==} 115 | dependencies: 116 | '@vlcn.io/wa-sqlite': 0.11.1 117 | '@vlcn.io/xplat-api': 0.3.0 118 | comlink: 4.3.1 119 | dev: false 120 | 121 | /@vlcn.io/wa-sqlite/0.11.1: 122 | resolution: {integrity: sha512-gMfV+M8ayzsQJOT27Jg0VLe1QYrvcb53zE29l3YHrsb0A4qi2DuQNSZrsW7OCxS0we3Pbp55oYvCiaq60+qsSg==} 123 | dev: false 124 | 125 | /@vlcn.io/xplat-api/0.3.0: 126 | resolution: {integrity: sha512-lbga584TeG/f/v31Z+MDi4AU66G3PpB+2q3XZtOVCiaCRaB8OESgiw2kUbzrMFQ5OPm4Nyqz0+KeS62RRrT6+g==} 127 | dependencies: 128 | comlink: 4.3.1 129 | dev: false 130 | 131 | /ansi-styles/3.2.1: 132 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 133 | engines: {node: '>=4'} 134 | dependencies: 135 | color-convert: 1.9.3 136 | dev: true 137 | 138 | /anymatch/3.1.3: 139 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 140 | engines: {node: '>= 8'} 141 | dependencies: 142 | normalize-path: 3.0.0 143 | picomatch: 2.3.1 144 | dev: true 145 | 146 | /atob/2.1.2: 147 | resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} 148 | engines: {node: '>= 4.5.0'} 149 | hasBin: true 150 | dev: true 151 | 152 | /balanced-match/1.0.2: 153 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 154 | dev: true 155 | 156 | /big.js/3.2.0: 157 | resolution: {integrity: sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==} 158 | dev: true 159 | 160 | /binary-extensions/2.2.0: 161 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 162 | engines: {node: '>=8'} 163 | dev: true 164 | 165 | /brace-expansion/1.1.11: 166 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 167 | dependencies: 168 | balanced-match: 1.0.2 169 | concat-map: 0.0.1 170 | dev: true 171 | 172 | /braces/3.0.2: 173 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 174 | engines: {node: '>=8'} 175 | dependencies: 176 | fill-range: 7.0.1 177 | dev: true 178 | 179 | /chalk/2.4.2: 180 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 181 | engines: {node: '>=4'} 182 | dependencies: 183 | ansi-styles: 3.2.1 184 | escape-string-regexp: 1.0.5 185 | supports-color: 5.5.0 186 | dev: true 187 | 188 | /chokidar/3.5.3: 189 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 190 | engines: {node: '>= 8.10.0'} 191 | dependencies: 192 | anymatch: 3.1.3 193 | braces: 3.0.2 194 | glob-parent: 5.1.2 195 | is-binary-path: 2.1.0 196 | is-glob: 4.0.3 197 | normalize-path: 3.0.0 198 | readdirp: 3.6.0 199 | optionalDependencies: 200 | fsevents: 2.3.2 201 | dev: true 202 | 203 | /color-convert/1.9.3: 204 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 205 | dependencies: 206 | color-name: 1.1.3 207 | dev: true 208 | 209 | /color-name/1.1.3: 210 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 211 | dev: true 212 | 213 | /comlink/4.3.1: 214 | resolution: {integrity: sha512-+YbhUdNrpBZggBAHWcgQMLPLH1KDF3wJpeqrCKieWQ8RL7atmgsgTQko1XEBK6PsecfopWNntopJ+ByYG1lRaA==} 215 | dev: false 216 | 217 | /concat-map/0.0.1: 218 | resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} 219 | dev: true 220 | 221 | /copy-anything/2.0.6: 222 | resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} 223 | dependencies: 224 | is-what: 3.14.1 225 | dev: true 226 | 227 | /css-parse/2.0.0: 228 | resolution: {integrity: sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==} 229 | dependencies: 230 | css: 2.2.4 231 | dev: true 232 | 233 | /css-selector-tokenizer/0.7.3: 234 | resolution: {integrity: sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==} 235 | dependencies: 236 | cssesc: 3.0.0 237 | fastparse: 1.1.2 238 | dev: true 239 | 240 | /css/2.2.4: 241 | resolution: {integrity: sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==} 242 | dependencies: 243 | inherits: 2.0.4 244 | source-map: 0.6.1 245 | source-map-resolve: 0.5.3 246 | urix: 0.1.0 247 | dev: true 248 | 249 | /cssesc/3.0.0: 250 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 251 | engines: {node: '>=4'} 252 | hasBin: true 253 | dev: true 254 | 255 | /csstype/3.1.1: 256 | resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} 257 | dev: true 258 | 259 | /debug/3.1.0: 260 | resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} 261 | peerDependencies: 262 | supports-color: '*' 263 | peerDependenciesMeta: 264 | supports-color: 265 | optional: true 266 | dependencies: 267 | ms: 2.0.0 268 | dev: true 269 | 270 | /debug/3.2.7: 271 | resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} 272 | peerDependencies: 273 | supports-color: '*' 274 | peerDependenciesMeta: 275 | supports-color: 276 | optional: true 277 | dependencies: 278 | ms: 2.1.3 279 | dev: true 280 | optional: true 281 | 282 | /decode-uri-component/0.2.0: 283 | resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} 284 | engines: {node: '>=0.10'} 285 | dev: true 286 | 287 | /dotenv/10.0.0: 288 | resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} 289 | engines: {node: '>=10'} 290 | dev: true 291 | 292 | /emojis-list/2.1.0: 293 | resolution: {integrity: sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==} 294 | engines: {node: '>= 0.10'} 295 | dev: true 296 | 297 | /errno/0.1.8: 298 | resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} 299 | hasBin: true 300 | requiresBuild: true 301 | dependencies: 302 | prr: 1.0.1 303 | dev: true 304 | optional: true 305 | 306 | /esbuild-android-64/0.15.16: 307 | resolution: {integrity: sha512-Vwkv/sT0zMSgPSVO3Jlt1pUbnZuOgtOQJkJkyyJFAlLe7BiT8e9ESzo0zQSx4c3wW4T6kGChmKDPMbWTgtliQA==} 308 | engines: {node: '>=12'} 309 | cpu: [x64] 310 | os: [android] 311 | requiresBuild: true 312 | dev: true 313 | optional: true 314 | 315 | /esbuild-android-arm64/0.15.16: 316 | resolution: {integrity: sha512-lqfKuofMExL5niNV3gnhMUYacSXfsvzTa/58sDlBET/hCOG99Zmeh+lz6kvdgvGOsImeo6J9SW21rFCogNPLxg==} 317 | engines: {node: '>=12'} 318 | cpu: [arm64] 319 | os: [android] 320 | requiresBuild: true 321 | dev: true 322 | optional: true 323 | 324 | /esbuild-darwin-64/0.15.16: 325 | resolution: {integrity: sha512-wo2VWk/n/9V2TmqUZ/KpzRjCEcr00n7yahEdmtzlrfQ3lfMCf3Wa+0sqHAbjk3C6CKkR3WKK/whkMq5Gj4Da9g==} 326 | engines: {node: '>=12'} 327 | cpu: [x64] 328 | os: [darwin] 329 | requiresBuild: true 330 | dev: true 331 | optional: true 332 | 333 | /esbuild-darwin-arm64/0.15.16: 334 | resolution: {integrity: sha512-fMXaUr5ou0M4WnewBKsspMtX++C1yIa3nJ5R2LSbLCfJT3uFdcRoU/NZjoM4kOMKyOD9Sa/2vlgN8G07K3SJnw==} 335 | engines: {node: '>=12'} 336 | cpu: [arm64] 337 | os: [darwin] 338 | requiresBuild: true 339 | dev: true 340 | optional: true 341 | 342 | /esbuild-freebsd-64/0.15.16: 343 | resolution: {integrity: sha512-UzIc0xlRx5x9kRuMr+E3+hlSOxa/aRqfuMfiYBXu2jJ8Mzej4lGL7+o6F5hzhLqWfWm1GWHNakIdlqg1ayaTNQ==} 344 | engines: {node: '>=12'} 345 | cpu: [x64] 346 | os: [freebsd] 347 | requiresBuild: true 348 | dev: true 349 | optional: true 350 | 351 | /esbuild-freebsd-arm64/0.15.16: 352 | resolution: {integrity: sha512-8xyiYuGc0DLZphFQIiYaLHlfoP+hAN9RHbE+Ibh8EUcDNHAqbQgUrQg7pE7Bo00rXmQ5Ap6KFgcR0b4ALZls1g==} 353 | engines: {node: '>=12'} 354 | cpu: [arm64] 355 | os: [freebsd] 356 | requiresBuild: true 357 | dev: true 358 | optional: true 359 | 360 | /esbuild-linux-32/0.15.16: 361 | resolution: {integrity: sha512-iGijUTV+0kIMyUVoynK0v+32Oi8yyp0xwMzX69GX+5+AniNy/C/AL1MjFTsozRp/3xQPl7jVux/PLe2ds10/2w==} 362 | engines: {node: '>=12'} 363 | cpu: [ia32] 364 | os: [linux] 365 | requiresBuild: true 366 | dev: true 367 | optional: true 368 | 369 | /esbuild-linux-64/0.15.16: 370 | resolution: {integrity: sha512-tuSOjXdLw7VzaUj89fIdAaQT7zFGbKBcz4YxbWrOiXkwscYgE7HtTxUavreBbnRkGxKwr9iT/gmeJWNm4djy/g==} 371 | engines: {node: '>=12'} 372 | cpu: [x64] 373 | os: [linux] 374 | requiresBuild: true 375 | dev: true 376 | optional: true 377 | 378 | /esbuild-linux-arm/0.15.16: 379 | resolution: {integrity: sha512-XKcrxCEXDTOuoRj5l12tJnkvuxXBMKwEC5j0JISw3ziLf0j4zIwXbKbTmUrKFWbo6ZgvNpa7Y5dnbsjVvH39bQ==} 380 | engines: {node: '>=12'} 381 | cpu: [arm] 382 | os: [linux] 383 | requiresBuild: true 384 | dev: true 385 | optional: true 386 | 387 | /esbuild-linux-arm64/0.15.16: 388 | resolution: {integrity: sha512-mPYksnfHnemNrvjrDhZyixL/AfbJN0Xn9S34ZOHYdh6/jJcNd8iTsv3JwJoEvTJqjMggjMhGUPJAdjnFBHoH8A==} 389 | engines: {node: '>=12'} 390 | cpu: [arm64] 391 | os: [linux] 392 | requiresBuild: true 393 | dev: true 394 | optional: true 395 | 396 | /esbuild-linux-mips64le/0.15.16: 397 | resolution: {integrity: sha512-kSJO2PXaxfm0pWY39+YX+QtpFqyyrcp0ZeI8QPTrcFVQoWEPiPVtOfTZeS3ZKedfH+Ga38c4DSzmKMQJocQv6A==} 398 | engines: {node: '>=12'} 399 | cpu: [mips64el] 400 | os: [linux] 401 | requiresBuild: true 402 | dev: true 403 | optional: true 404 | 405 | /esbuild-linux-ppc64le/0.15.16: 406 | resolution: {integrity: sha512-NimPikwkBY0yGABw6SlhKrtT35sU4O23xkhlrTT/O6lSxv3Pm5iSc6OYaqVAHWkLdVf31bF4UDVFO+D990WpAA==} 407 | engines: {node: '>=12'} 408 | cpu: [ppc64] 409 | os: [linux] 410 | requiresBuild: true 411 | dev: true 412 | optional: true 413 | 414 | /esbuild-linux-riscv64/0.15.16: 415 | resolution: {integrity: sha512-ty2YUHZlwFOwp7pR+J87M4CVrXJIf5ZZtU/umpxgVJBXvWjhziSLEQxvl30SYfUPq0nzeWKBGw5i/DieiHeKfw==} 416 | engines: {node: '>=12'} 417 | cpu: [riscv64] 418 | os: [linux] 419 | requiresBuild: true 420 | dev: true 421 | optional: true 422 | 423 | /esbuild-linux-s390x/0.15.16: 424 | resolution: {integrity: sha512-VkZaGssvPDQtx4fvVdZ9czezmyWyzpQhEbSNsHZZN0BHvxRLOYAQ7sjay8nMQwYswP6O2KlZluRMNPYefFRs+w==} 425 | engines: {node: '>=12'} 426 | cpu: [s390x] 427 | os: [linux] 428 | requiresBuild: true 429 | dev: true 430 | optional: true 431 | 432 | /esbuild-netbsd-64/0.15.16: 433 | resolution: {integrity: sha512-ElQ9rhdY51et6MJTWrCPbqOd/YuPowD7Cxx3ee8wlmXQQVW7UvQI6nSprJ9uVFQISqSF5e5EWpwWqXZsECLvXg==} 434 | engines: {node: '>=12'} 435 | cpu: [x64] 436 | os: [netbsd] 437 | requiresBuild: true 438 | dev: true 439 | optional: true 440 | 441 | /esbuild-openbsd-64/0.15.16: 442 | resolution: {integrity: sha512-KgxMHyxMCT+NdLQE1zVJEsLSt2QQBAvJfmUGDmgEq8Fvjrf6vSKB00dVHUEDKcJwMID6CdgCpvYNt999tIYhqA==} 443 | engines: {node: '>=12'} 444 | cpu: [x64] 445 | os: [openbsd] 446 | requiresBuild: true 447 | dev: true 448 | optional: true 449 | 450 | /esbuild-sunos-64/0.15.16: 451 | resolution: {integrity: sha512-exSAx8Phj7QylXHlMfIyEfNrmqnLxFqLxdQF6MBHPdHAjT7fsKaX6XIJn+aQEFiOcE4X8e7VvdMCJ+WDZxjSRQ==} 452 | engines: {node: '>=12'} 453 | cpu: [x64] 454 | os: [sunos] 455 | requiresBuild: true 456 | dev: true 457 | optional: true 458 | 459 | /esbuild-windows-32/0.15.16: 460 | resolution: {integrity: sha512-zQgWpY5pUCSTOwqKQ6/vOCJfRssTvxFuEkpB4f2VUGPBpdddZfdj8hbZuFRdZRPIVHvN7juGcpgCA/XCF37mAQ==} 461 | engines: {node: '>=12'} 462 | cpu: [ia32] 463 | os: [win32] 464 | requiresBuild: true 465 | dev: true 466 | optional: true 467 | 468 | /esbuild-windows-64/0.15.16: 469 | resolution: {integrity: sha512-HjW1hHRLSncnM3MBCP7iquatHVJq9l0S2xxsHHj4yzf4nm9TU4Z7k4NkeMlD/dHQ4jPlQQhwcMvwbJiOefSuZw==} 470 | engines: {node: '>=12'} 471 | cpu: [x64] 472 | os: [win32] 473 | requiresBuild: true 474 | dev: true 475 | optional: true 476 | 477 | /esbuild-windows-arm64/0.15.16: 478 | resolution: {integrity: sha512-oCcUKrJaMn04Vxy9Ekd8x23O8LoU01+4NOkQ2iBToKgnGj5eo1vU9i27NQZ9qC8NFZgnQQZg5oZWAejmbsppNA==} 479 | engines: {node: '>=12'} 480 | cpu: [arm64] 481 | os: [win32] 482 | requiresBuild: true 483 | dev: true 484 | optional: true 485 | 486 | /esbuild/0.15.16: 487 | resolution: {integrity: sha512-o6iS9zxdHrrojjlj6pNGC2NAg86ECZqIETswTM5KmJitq+R1YmahhWtMumeQp9lHqJaROGnsBi2RLawGnfo5ZQ==} 488 | engines: {node: '>=12'} 489 | hasBin: true 490 | requiresBuild: true 491 | optionalDependencies: 492 | '@esbuild/android-arm': 0.15.16 493 | '@esbuild/linux-loong64': 0.15.16 494 | esbuild-android-64: 0.15.16 495 | esbuild-android-arm64: 0.15.16 496 | esbuild-darwin-64: 0.15.16 497 | esbuild-darwin-arm64: 0.15.16 498 | esbuild-freebsd-64: 0.15.16 499 | esbuild-freebsd-arm64: 0.15.16 500 | esbuild-linux-32: 0.15.16 501 | esbuild-linux-64: 0.15.16 502 | esbuild-linux-arm: 0.15.16 503 | esbuild-linux-arm64: 0.15.16 504 | esbuild-linux-mips64le: 0.15.16 505 | esbuild-linux-ppc64le: 0.15.16 506 | esbuild-linux-riscv64: 0.15.16 507 | esbuild-linux-s390x: 0.15.16 508 | esbuild-netbsd-64: 0.15.16 509 | esbuild-openbsd-64: 0.15.16 510 | esbuild-sunos-64: 0.15.16 511 | esbuild-windows-32: 0.15.16 512 | esbuild-windows-64: 0.15.16 513 | esbuild-windows-arm64: 0.15.16 514 | dev: true 515 | 516 | /escape-string-regexp/1.0.5: 517 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 518 | engines: {node: '>=0.8.0'} 519 | dev: true 520 | 521 | /fastparse/1.1.2: 522 | resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} 523 | dev: true 524 | 525 | /fill-range/7.0.1: 526 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 527 | engines: {node: '>=8'} 528 | dependencies: 529 | to-regex-range: 5.0.1 530 | dev: true 531 | 532 | /fs.realpath/1.0.0: 533 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 534 | dev: true 535 | 536 | /fsevents/2.3.2: 537 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 538 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 539 | os: [darwin] 540 | requiresBuild: true 541 | dev: true 542 | optional: true 543 | 544 | /function-bind/1.1.1: 545 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 546 | dev: true 547 | 548 | /generic-names/1.0.3: 549 | resolution: {integrity: sha512-b6OHfQuKasIKM9b6YPkX+KUj/TLBTx3B/1aT1T5F12FEuEqyFMdr59OMS53aoaSw8eVtapdqieX6lbg5opaOhA==} 550 | dependencies: 551 | loader-utils: 0.2.17 552 | dev: true 553 | 554 | /glob-parent/5.1.2: 555 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 556 | engines: {node: '>= 6'} 557 | dependencies: 558 | is-glob: 4.0.3 559 | dev: true 560 | 561 | /glob/7.2.3: 562 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 563 | dependencies: 564 | fs.realpath: 1.0.0 565 | inflight: 1.0.6 566 | inherits: 2.0.4 567 | minimatch: 3.1.2 568 | once: 1.4.0 569 | path-is-absolute: 1.0.1 570 | dev: true 571 | 572 | /graceful-fs/4.2.10: 573 | resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} 574 | requiresBuild: true 575 | dev: true 576 | optional: true 577 | 578 | /has-flag/3.0.0: 579 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 580 | engines: {node: '>=4'} 581 | dev: true 582 | 583 | /has/1.0.3: 584 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 585 | engines: {node: '>= 0.4.0'} 586 | dependencies: 587 | function-bind: 1.1.1 588 | dev: true 589 | 590 | /iconv-lite/0.6.3: 591 | resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 592 | engines: {node: '>=0.10.0'} 593 | dependencies: 594 | safer-buffer: 2.1.2 595 | dev: true 596 | optional: true 597 | 598 | /icss-utils/3.0.1: 599 | resolution: {integrity: sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==} 600 | dependencies: 601 | postcss: 6.0.23 602 | dev: true 603 | 604 | /icss-utils/5.1.0_postcss@8.4.19: 605 | resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} 606 | engines: {node: ^10 || ^12 || >= 14} 607 | peerDependencies: 608 | postcss: ^8.1.0 609 | dependencies: 610 | postcss: 8.4.19 611 | dev: true 612 | 613 | /image-size/0.5.5: 614 | resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} 615 | engines: {node: '>=0.10.0'} 616 | hasBin: true 617 | requiresBuild: true 618 | dev: true 619 | optional: true 620 | 621 | /immutable/4.1.0: 622 | resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} 623 | dev: true 624 | 625 | /inflight/1.0.6: 626 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 627 | dependencies: 628 | once: 1.4.0 629 | wrappy: 1.0.2 630 | dev: true 631 | 632 | /inherits/2.0.4: 633 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 634 | dev: true 635 | 636 | /is-binary-path/2.1.0: 637 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 638 | engines: {node: '>=8'} 639 | dependencies: 640 | binary-extensions: 2.2.0 641 | dev: true 642 | 643 | /is-core-module/2.11.0: 644 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 645 | dependencies: 646 | has: 1.0.3 647 | dev: true 648 | 649 | /is-extglob/2.1.1: 650 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 651 | engines: {node: '>=0.10.0'} 652 | dev: true 653 | 654 | /is-glob/4.0.3: 655 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 656 | engines: {node: '>=0.10.0'} 657 | dependencies: 658 | is-extglob: 2.1.1 659 | dev: true 660 | 661 | /is-number/7.0.0: 662 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 663 | engines: {node: '>=0.12.0'} 664 | dev: true 665 | 666 | /is-what/3.14.1: 667 | resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} 668 | dev: true 669 | 670 | /js-tokens/4.0.0: 671 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 672 | 673 | /json5/0.5.1: 674 | resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} 675 | hasBin: true 676 | dev: true 677 | 678 | /json5/1.0.1: 679 | resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} 680 | hasBin: true 681 | dependencies: 682 | minimist: 1.2.7 683 | dev: true 684 | 685 | /less/4.1.3: 686 | resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==} 687 | engines: {node: '>=6'} 688 | hasBin: true 689 | dependencies: 690 | copy-anything: 2.0.6 691 | parse-node-version: 1.0.1 692 | tslib: 2.4.1 693 | optionalDependencies: 694 | errno: 0.1.8 695 | graceful-fs: 4.2.10 696 | image-size: 0.5.5 697 | make-dir: 2.1.0 698 | mime: 1.6.0 699 | needle: 3.2.0 700 | source-map: 0.6.1 701 | transitivePeerDependencies: 702 | - supports-color 703 | dev: true 704 | 705 | /lilconfig/2.0.6: 706 | resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} 707 | engines: {node: '>=10'} 708 | dev: true 709 | 710 | /loader-utils/0.2.17: 711 | resolution: {integrity: sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==} 712 | dependencies: 713 | big.js: 3.2.0 714 | emojis-list: 2.1.0 715 | json5: 0.5.1 716 | object-assign: 4.1.1 717 | dev: true 718 | 719 | /lodash.camelcase/4.3.0: 720 | resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} 721 | dev: true 722 | 723 | /lodash/4.17.21: 724 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 725 | dev: true 726 | 727 | /loose-envify/1.4.0: 728 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 729 | hasBin: true 730 | dependencies: 731 | js-tokens: 4.0.0 732 | 733 | /make-dir/2.1.0: 734 | resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} 735 | engines: {node: '>=6'} 736 | requiresBuild: true 737 | dependencies: 738 | pify: 4.0.1 739 | semver: 5.7.1 740 | dev: true 741 | optional: true 742 | 743 | /mime/1.6.0: 744 | resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} 745 | engines: {node: '>=4'} 746 | hasBin: true 747 | requiresBuild: true 748 | dev: true 749 | optional: true 750 | 751 | /minimatch/3.1.2: 752 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 753 | dependencies: 754 | brace-expansion: 1.1.11 755 | dev: true 756 | 757 | /minimist/1.2.7: 758 | resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} 759 | dev: true 760 | 761 | /mkdirp/1.0.4: 762 | resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} 763 | engines: {node: '>=10'} 764 | hasBin: true 765 | dev: true 766 | 767 | /ms/2.0.0: 768 | resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 769 | dev: true 770 | 771 | /ms/2.1.3: 772 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 773 | dev: true 774 | optional: true 775 | 776 | /nanoid/3.3.4: 777 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 778 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 779 | hasBin: true 780 | dev: true 781 | 782 | /needle/3.2.0: 783 | resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} 784 | engines: {node: '>= 4.4.x'} 785 | hasBin: true 786 | requiresBuild: true 787 | dependencies: 788 | debug: 3.2.7 789 | iconv-lite: 0.6.3 790 | sax: 1.2.4 791 | transitivePeerDependencies: 792 | - supports-color 793 | dev: true 794 | optional: true 795 | 796 | /normalize-path/3.0.0: 797 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 798 | engines: {node: '>=0.10.0'} 799 | dev: true 800 | 801 | /object-assign/4.1.1: 802 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 803 | engines: {node: '>=0.10.0'} 804 | dev: true 805 | 806 | /ohm-js/16.4.0: 807 | resolution: {integrity: sha512-u1QI5h2w29I4838+/m32rzqfNNH1Qej9L6O1MTZZMx7bVOu09orc/TO0HRVeYh5jStieZ3INszM7oqbCdx2x7A==} 808 | engines: {node: '>=0.12.1'} 809 | dev: false 810 | 811 | /once/1.4.0: 812 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 813 | dependencies: 814 | wrappy: 1.0.2 815 | dev: true 816 | 817 | /parse-node-version/1.0.1: 818 | resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} 819 | engines: {node: '>= 0.10'} 820 | dev: true 821 | 822 | /path-is-absolute/1.0.1: 823 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 824 | engines: {node: '>=0.10.0'} 825 | dev: true 826 | 827 | /path-parse/1.0.7: 828 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 829 | dev: true 830 | 831 | /picocolors/1.0.0: 832 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 833 | dev: true 834 | 835 | /picomatch/2.3.1: 836 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 837 | engines: {node: '>=8.6'} 838 | dev: true 839 | 840 | /pify/4.0.1: 841 | resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} 842 | engines: {node: '>=6'} 843 | dev: true 844 | optional: true 845 | 846 | /postcss-filter-plugins/3.0.1: 847 | resolution: {integrity: sha512-tRKbW4wWBEkSSFuJtamV2wkiV9rj6Yy7P3Y13+zaynlPEEZt8EgYKn3y/RBpMeIhNmHXFlSdzofml65hD5OafA==} 848 | dependencies: 849 | postcss: 6.0.23 850 | dev: true 851 | 852 | /postcss-icss-keyframes/0.2.1: 853 | resolution: {integrity: sha512-4m+hLY5TVqoTM198KKnzdNudyu1OvtqwD+8kVZ9PNiEO4+IfHYoyVvEXsOHjV8nZ1k6xowf+nY4HlUfZhOFvvw==} 854 | dependencies: 855 | icss-utils: 3.0.1 856 | postcss: 6.0.23 857 | postcss-value-parser: 3.3.1 858 | dev: true 859 | 860 | /postcss-icss-selectors/2.0.3: 861 | resolution: {integrity: sha512-dxFtq+wscbU9faJaH8kIi98vvCPDbt+qg1g9GoG0os1PY3UvgY1Y2G06iZrZb1iVC9cyFfafwSY1IS+IQpRQ4w==} 862 | dependencies: 863 | css-selector-tokenizer: 0.7.3 864 | generic-names: 1.0.3 865 | icss-utils: 3.0.1 866 | lodash: 4.17.21 867 | postcss: 6.0.23 868 | dev: true 869 | 870 | /postcss-load-config/3.1.4_postcss@8.4.19: 871 | resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 872 | engines: {node: '>= 10'} 873 | peerDependencies: 874 | postcss: '>=8.0.9' 875 | ts-node: '>=9.0.0' 876 | peerDependenciesMeta: 877 | postcss: 878 | optional: true 879 | ts-node: 880 | optional: true 881 | dependencies: 882 | lilconfig: 2.0.6 883 | postcss: 8.4.19 884 | yaml: 1.10.2 885 | dev: true 886 | 887 | /postcss-value-parser/3.3.1: 888 | resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} 889 | dev: true 890 | 891 | /postcss/6.0.23: 892 | resolution: {integrity: sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==} 893 | engines: {node: '>=4.0.0'} 894 | dependencies: 895 | chalk: 2.4.2 896 | source-map: 0.6.1 897 | supports-color: 5.5.0 898 | dev: true 899 | 900 | /postcss/8.4.19: 901 | resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} 902 | engines: {node: ^10 || ^12 || >=14} 903 | dependencies: 904 | nanoid: 3.3.4 905 | picocolors: 1.0.0 906 | source-map-js: 1.0.2 907 | dev: true 908 | 909 | /prr/1.0.1: 910 | resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} 911 | dev: true 912 | optional: true 913 | 914 | /react-dom/18.2.0_react@18.2.0: 915 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 916 | peerDependencies: 917 | react: ^18.2.0 918 | dependencies: 919 | loose-envify: 1.4.0 920 | react: 18.2.0 921 | scheduler: 0.23.0 922 | dev: false 923 | 924 | /react/18.2.0: 925 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 926 | engines: {node: '>=0.10.0'} 927 | dependencies: 928 | loose-envify: 1.4.0 929 | 930 | /readdirp/3.6.0: 931 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 932 | engines: {node: '>=8.10.0'} 933 | dependencies: 934 | picomatch: 2.3.1 935 | dev: true 936 | 937 | /reserved-words/0.1.2: 938 | resolution: {integrity: sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==} 939 | dev: true 940 | 941 | /resolve-url/0.2.1: 942 | resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} 943 | deprecated: https://github.com/lydell/resolve-url#deprecated 944 | dev: true 945 | 946 | /resolve/1.22.1: 947 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 948 | hasBin: true 949 | dependencies: 950 | is-core-module: 2.11.0 951 | path-parse: 1.0.7 952 | supports-preserve-symlinks-flag: 1.0.0 953 | dev: true 954 | 955 | /rollup/2.79.1: 956 | resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} 957 | engines: {node: '>=10.0.0'} 958 | hasBin: true 959 | optionalDependencies: 960 | fsevents: 2.3.2 961 | dev: true 962 | 963 | /safer-buffer/2.1.2: 964 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 965 | dev: true 966 | 967 | /sass/1.56.1: 968 | resolution: {integrity: sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==} 969 | engines: {node: '>=12.0.0'} 970 | hasBin: true 971 | dependencies: 972 | chokidar: 3.5.3 973 | immutable: 4.1.0 974 | source-map-js: 1.0.2 975 | dev: true 976 | 977 | /sax/1.2.4: 978 | resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} 979 | dev: true 980 | 981 | /scheduler/0.23.0: 982 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 983 | dependencies: 984 | loose-envify: 1.4.0 985 | dev: false 986 | 987 | /semver/5.7.1: 988 | resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} 989 | hasBin: true 990 | dev: true 991 | optional: true 992 | 993 | /semver/6.3.0: 994 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 995 | hasBin: true 996 | dev: true 997 | 998 | /source-map-js/1.0.2: 999 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 1000 | engines: {node: '>=0.10.0'} 1001 | dev: true 1002 | 1003 | /source-map-resolve/0.5.3: 1004 | resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} 1005 | deprecated: See https://github.com/lydell/source-map-resolve#deprecated 1006 | dependencies: 1007 | atob: 2.1.2 1008 | decode-uri-component: 0.2.0 1009 | resolve-url: 0.2.1 1010 | source-map-url: 0.4.1 1011 | urix: 0.1.0 1012 | dev: true 1013 | 1014 | /source-map-url/0.4.1: 1015 | resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} 1016 | deprecated: See https://github.com/lydell/source-map-url#deprecated 1017 | dev: true 1018 | 1019 | /source-map/0.6.1: 1020 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 1021 | engines: {node: '>=0.10.0'} 1022 | dev: true 1023 | 1024 | /source-map/0.7.4: 1025 | resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} 1026 | engines: {node: '>= 8'} 1027 | dev: true 1028 | 1029 | /strip-bom/3.0.0: 1030 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 1031 | engines: {node: '>=4'} 1032 | dev: true 1033 | 1034 | /stylus/0.54.8: 1035 | resolution: {integrity: sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==} 1036 | hasBin: true 1037 | dependencies: 1038 | css-parse: 2.0.0 1039 | debug: 3.1.0 1040 | glob: 7.2.3 1041 | mkdirp: 1.0.4 1042 | safer-buffer: 2.1.2 1043 | sax: 1.2.4 1044 | semver: 6.3.0 1045 | source-map: 0.7.4 1046 | transitivePeerDependencies: 1047 | - supports-color 1048 | dev: true 1049 | 1050 | /supports-color/5.5.0: 1051 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1052 | engines: {node: '>=4'} 1053 | dependencies: 1054 | has-flag: 3.0.0 1055 | dev: true 1056 | 1057 | /supports-preserve-symlinks-flag/1.0.0: 1058 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1059 | engines: {node: '>= 0.4'} 1060 | dev: true 1061 | 1062 | /to-regex-range/5.0.1: 1063 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1064 | engines: {node: '>=8.0'} 1065 | dependencies: 1066 | is-number: 7.0.0 1067 | dev: true 1068 | 1069 | /tsconfig-paths/3.14.1: 1070 | resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} 1071 | dependencies: 1072 | '@types/json5': 0.0.29 1073 | json5: 1.0.1 1074 | minimist: 1.2.7 1075 | strip-bom: 3.0.0 1076 | dev: true 1077 | 1078 | /tslib/2.4.1: 1079 | resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} 1080 | dev: true 1081 | 1082 | /typescript-plugin-css-modules/3.4.0_typescript@4.9.3: 1083 | resolution: {integrity: sha512-2MdjfSg4MGex1csCWRUwKD+MpgnvcvLLr9bSAMemU/QYGqBsXdez0cc06H/fFhLtRoKJjXg6PSTur3Gy1Umhpw==} 1084 | peerDependencies: 1085 | typescript: '>=3.0.0' 1086 | dependencies: 1087 | dotenv: 10.0.0 1088 | icss-utils: 5.1.0_postcss@8.4.19 1089 | less: 4.1.3 1090 | lodash.camelcase: 4.3.0 1091 | postcss: 8.4.19 1092 | postcss-filter-plugins: 3.0.1 1093 | postcss-icss-keyframes: 0.2.1 1094 | postcss-icss-selectors: 2.0.3 1095 | postcss-load-config: 3.1.4_postcss@8.4.19 1096 | reserved-words: 0.1.2 1097 | sass: 1.56.1 1098 | stylus: 0.54.8 1099 | tsconfig-paths: 3.14.1 1100 | typescript: 4.9.3 1101 | transitivePeerDependencies: 1102 | - supports-color 1103 | - ts-node 1104 | dev: true 1105 | 1106 | /typescript/4.9.3: 1107 | resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} 1108 | engines: {node: '>=4.2.0'} 1109 | hasBin: true 1110 | dev: true 1111 | 1112 | /urix/0.1.0: 1113 | resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} 1114 | deprecated: Please see https://github.com/lydell/urix#deprecated 1115 | dev: true 1116 | 1117 | /vite/3.2.4: 1118 | resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} 1119 | engines: {node: ^14.18.0 || >=16.0.0} 1120 | hasBin: true 1121 | peerDependencies: 1122 | '@types/node': '>= 14' 1123 | less: '*' 1124 | sass: '*' 1125 | stylus: '*' 1126 | sugarss: '*' 1127 | terser: ^5.4.0 1128 | peerDependenciesMeta: 1129 | '@types/node': 1130 | optional: true 1131 | less: 1132 | optional: true 1133 | sass: 1134 | optional: true 1135 | stylus: 1136 | optional: true 1137 | sugarss: 1138 | optional: true 1139 | terser: 1140 | optional: true 1141 | dependencies: 1142 | esbuild: 0.15.16 1143 | postcss: 8.4.19 1144 | resolve: 1.22.1 1145 | rollup: 2.79.1 1146 | optionalDependencies: 1147 | fsevents: 2.3.2 1148 | dev: true 1149 | 1150 | /wrappy/1.0.2: 1151 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1152 | dev: true 1153 | 1154 | /yaml/1.10.2: 1155 | resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 1156 | engines: {node: '>= 6'} 1157 | dev: true 1158 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - pkg/dialect 3 | - pkg/example 4 | - pkg/react 5 | -------------------------------------------------------------------------------- /scratch/scratch.md: -------------------------------------------------------------------------------- 1 | ```js 2 | let fragCount = 0; 3 | 4 | const fragRefs = new Map(); 5 | 6 | export function frag( 7 | strings: TemplateStringsArray, 8 | ...values: any[] 9 | ): Frag { 10 | return { 11 | id: ++fragCount, 12 | // TODO: should shadow fields 13 | // or should de-dupe fields in the final composed query 14 | embedding: String.raw({ raw: strings }, ...values), 15 | // ^- field only frags have no standalone? 16 | // the _simplest_ first pass would be to 17 | // not do any splitting and literally 18 | // re-run the whole composed query then _diff_ 19 | // by frag. 20 | // - data comes in 21 | // - we mutate frag refs on props (yes, mutate a prop) 22 | // - useFrag listens to those refs 23 | // - useFrag diffs 24 | // - if different, set state 25 | // 26 | // can we rm react then? since react 27 | // will dom diff too 28 | // but if we data diff, why dom diff? 29 | // we are pretty sure what'll be touched. 30 | // 31 | // put db in worker for this approach? 32 | }; 33 | } 34 | 35 | export type Frag = { 36 | id: number, 37 | embedding: string, 38 | standalone?: string, 39 | }; 40 | 41 | export type FragRef = {}; 42 | 43 | export function include(frag: Frag) { 44 | return frag.embedding; 45 | } 46 | 47 | // can only frag on fields 48 | export function useFrag(data: T) { 49 | // if there's a select we can hoist it separately? 50 | // and bind to it separately? 51 | // 1. run the query 52 | // 2. subscribe to it 53 | // 3. pull semantics from it 54 | // looks up frag from fragRefs 55 | // subscribes to it for state updates 56 | } 57 | 58 | export function useQuery() { 59 | // goes thru query 60 | // query is not yet compiled 61 | // need to know the path to each 62 | // fragment 63 | // 64 | // so when we traverse the json tree we know what frag to go to.. 65 | // or we re-key things 66 | } 67 | 68 | /* 69 | Algo: 70 | - Update received 71 | - Start diffing JSON at useQuery / root level 72 | - Once we hit a difference, look up the frag ref 73 | - Push that 74 | 75 | Or... 76 | 77 | Remove all frags. 78 | Flatten the response based on fragid. 79 | 80 | Diff each fragid separately 81 | 82 | Update components that use those fragids. 83 | 84 | What if someone uses a frag inside an array of values? 85 | 86 | Todos.map(t => ) 87 | 88 | SELECT {id, content: (SELECT {} FROM todo)} FROM todos; 89 | 90 | if content is a frag... 91 | that frag has many values. 92 | 93 | We'd need to diff against each value for each instance 94 | of the component using the frag. 95 | 96 | Arrays and keys :| 97 | 98 | Decomposing the selects is one option and subscribe at the 99 | point or whatever level. 100 | 101 | Require users to just use useQuery... 102 | */ 103 | ``` 104 | -------------------------------------------------------------------------------- /tsconfig-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strictNullChecks": true, 5 | "module": "esnext", 6 | "target": "esnext", 7 | "skipLibCheck": true, 8 | "moduleResolution": "Node", 9 | "baseUrl": "./src/", 10 | "declaration": true, 11 | "allowJs": true, 12 | "composite": true, 13 | "declarationMap": true, 14 | "incremental": true, 15 | "strict": true 16 | } 17 | } 18 | --------------------------------------------------------------------------------