@torpor/view 0.0.14 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +5 -5
- package/dist/compile.cjs +77 -32
- package/dist/compile.cjs.map +1 -1
- package/dist/compile.js +77 -32
- package/dist/compile.js.map +1 -1
- package/dist/index.cjs +31 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +31 -14
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +4 -4
- package/scripts/copyToRepl.ts +1 -1
- package/src/compile/build/client/buildCode.ts +2 -11
- package/src/compile/build/client/buildComponentNode.ts +21 -5
- package/src/compile/build/client/buildElementNode.ts +27 -10
- package/src/compile/build/client/buildFragment.ts +37 -1
- package/src/compile/build/client/buildHtmlNode.ts +1 -0
- package/src/compile/build/client/buildSlotNode.ts +4 -1
- package/src/compile/build/server/buildServerComponentNode.ts +4 -1
- package/src/compile/build/server/buildServerElementNode.ts +5 -2
- package/src/compile/build/server/buildServerSlotNode.ts +4 -1
- package/src/compile/parse/parseCode.ts +20 -12
- package/src/index.ts +0 -2
- package/src/motion/animate.ts +10 -6
- package/src/render/$unwrap.ts +1 -1
- package/src/render/addFragment.ts +14 -4
- package/src/render/hydrate.ts +7 -0
- package/src/render/nodeNext.ts +14 -7
- package/src/render/runControlBranch.ts +11 -1
- package/src/render/runList.ts +8 -2
- package/test/attributes/attributes.test.ts +3 -0
- package/test/attributes/components/Attributes.torp +6 -1
- package/test/attributes/components/output/Attributes-client.ts +6 -2
- package/test/attributes/components/output/Attributes-server.ts +2 -1
- package/test/attributes/components/temp/{Attributes-client-c4812cb9307eac6ff44f90f3358a1811b52c7390.ts → Attributes-client-7b8f7b9996208e8d2d0a12d4f4a40a73df63d9d8.ts} +6 -2
- package/test/attributes/components/temp/{Attributes-server-a7ebed503f2169f7c900d4613531082f1023b086.ts → Attributes-server-a1289434a5a801be1d63bfc85b621579e06452f0.ts} +2 -1
- package/test/await/await.test.ts +2 -4
- package/test/await/components/output/Await-client.ts +4 -4
- package/test/await/components/temp/{Await-client-6ce3ac610ce79ae3b474c81964b715e6f3d966da.ts → Await-client-a7bf000bf2b59a3d5251a0fa18ec79890a52a547.ts} +4 -4
- package/test/bench/bench.bench.ts +5 -7
- package/test/bench/components/output/Bench-client.ts +208 -0
- package/test/bench/components/output/Bench-server.ts +130 -0
- package/test/bench/components/temp/{Bench-client-5fee290225ae4771aa847360006123671e8f17f1.ts → Bench-client-fca94b485c6263778751927240ab3ca4048d7a10.ts} +10 -10
- package/test/bind/bind.test.ts +3 -5
- package/test/bind/component.test.ts +45 -0
- package/test/bind/components/BindComponent.torp +29 -0
- package/test/bind/components/BindText.torp +2 -2
- package/test/bind/components/output/BindComponent-client.ts +87 -0
- package/test/bind/components/output/BindComponent-server.ts +52 -0
- package/test/bind/components/output/BindText-client.ts +3 -3
- package/test/bind/components/temp/BindComponent-client-a645474748485a878871c062ad69e6bcf35e6550.ts +87 -0
- package/test/bind/components/temp/BindComponent-server-c557e7aa944517ab87415b8bb35b41b0034254e7.ts +52 -0
- package/test/bind/components/temp/{BindText-client-9e2f542e13bcbf9a44eab2c5a79d67ddb128f928.ts → BindText-client-d5f7d721df55020ef337f660e5d278eb80fcc330.ts} +3 -3
- package/test/build-server/build-server-element-node.test.ts +1 -1
- package/test/buildOutputFiles.ts +6 -3
- package/test/child-component/components/output/ParentChild-client.ts +3 -2
- package/test/child-component/components/output/ParentChild-server.ts +1 -0
- package/test/child-component/components/temp/{ParentChild-client-8f00a3a31a7f666990765fc4755b62a39c855226.ts → ParentChild-client-eaefb0cbfd251badab3c57ae2037d973f785a1b8.ts} +3 -2
- package/test/child-component/components/temp/{ParentChild-server-9c791bdfa521c3f6549857a34a6cd414fa3c9e80.ts → ParentChild-server-8f2fc556f87867e6e3393e2e9e6d696cda107b69.ts} +1 -0
- package/test/class/components/output/Class-client.ts +7 -6
- package/test/class/components/output/Class-server.ts +1 -0
- package/test/class/components/temp/{Class-client-8bf02b6a0c85674d341617dfb755b285b1af89cf.ts → Class-client-dc885e1e391f38973bd9ea25b7475b07f7c23960.ts} +7 -6
- package/test/class/components/temp/{Class-server-dd71b6ec62f40231917a912819520fc614f017ae.ts → Class-server-d1a2463ba432e10c6f68bd59d1d31949c5a2044f.ts} +1 -0
- package/test/component/components/output/Component-client.ts +3 -2
- package/test/component/components/output/Component-server.ts +1 -1
- package/test/component/components/output/Header-client.ts +2 -1
- package/test/component/components/output/Header-server.ts +1 -0
- package/test/component/components/temp/{Component-client-32cd481f03e25d10b8e93947a2ff8773135b4975.ts → Component-client-a2fb6f30fc340bac909b64cb4f5ac68cde376de3.ts} +3 -2
- package/test/component/components/temp/{Component-server-11542f55405218c0b471172cac1d6a1a4edb5c09.ts → Component-server-40be12cd528ccf768f1ad40ef2a435ad2b2a2d71.ts} +1 -1
- package/test/component/components/temp/{Header-client-ac151eea86e3f6b058fab101661e13ae73864968.ts → Header-client-75cb4aa868295ac168c16ba7b275fbb5ab9256f9.ts} +2 -1
- package/test/component/components/temp/{Header-server-4f10f2332f3ca7a097517cfb938ab1e6f31d68ac.ts → Header-server-f73307874bec34a95dcd152d7f83a3ad13a0f4ac.ts} +1 -0
- package/test/effects/components/output/For-client.ts +3 -2
- package/test/effects/components/output/For-server.ts +1 -0
- package/test/effects/components/output/If-client.ts +4 -3
- package/test/effects/components/output/If-server.ts +1 -0
- package/test/effects/components/output/NestedIf-client.ts +4 -3
- package/test/effects/components/output/NestedIf-server.ts +1 -0
- package/test/effects/components/temp/{For-client-887b1758cf5c80f64708a47369e0e6ce44ffa20f.ts → For-client-d8d4e4424ec3238fe9f79cc907d673612b63bcdf.ts} +3 -2
- package/test/effects/components/temp/{For-server-8e1c7393b102c870167dd086cbee45c47e614dfa.ts → For-server-1f853c161bea31a1a5b11b00d7a021b70c778066.ts} +1 -0
- package/test/effects/components/temp/{If-client-bfc548ef699b91f33e604f066211ce6269cc9506.ts → If-client-bb06988422395321bf298a75bf5563c6f750f776.ts} +4 -3
- package/test/effects/components/temp/{If-server-8c213b1a82cd0a5c2bccfeb90ba8bf01fa4672d2.ts → If-server-97e3cbe059306fc607985dcd1b187df3a278d979.ts} +1 -0
- package/test/effects/components/temp/{NestedIf-client-9e9155398f240345af392194063adc6e42dda80c.ts → NestedIf-client-dc880c1ec92e716ec730dfa0bac0e3d9265bdf27.ts} +4 -3
- package/test/effects/components/temp/{NestedIf-server-5f11d075c2ff224ee5feb7f61aa41aea8af44313.ts → NestedIf-server-9f199a33bae5d5fe34920d6a419937537a2b18dc.ts} +1 -0
- package/test/events/components/output/Increment-client.ts +2 -2
- package/test/events/components/temp/{Increment-client-35c275d15e94e4aa7625af12c45210521995ead5.ts → Increment-client-41bd7bc91aac8c7a9bf73527c8f7ba1794b09ab3.ts} +2 -2
- package/test/events/events.test.ts +2 -3
- package/test/for/components/ForEscape.torp +1 -1
- package/test/for/components/output/For-client.ts +1 -1
- package/test/for/components/output/ForEscape-client.ts +4 -4
- package/test/for/components/output/ForIn-client.ts +3 -2
- package/test/for/components/output/ForIn-server.ts +1 -0
- package/test/for/components/output/ForOf-client.ts +3 -2
- package/test/for/components/output/ForOf-server.ts +1 -0
- package/test/for/components/temp/{For-client-1f6e475347f0474375f12a7c24b0b293e3942aa7.ts → For-client-0be5994e98c07a3455cd8a18a2b1b8ef3605aba6.ts} +1 -1
- package/test/for/components/temp/{ForEscape-client-80d3078cf15001f2ab37b0ec63cfce7267a8a166.ts → ForEscape-client-a973a145e28b32ca55fe3dca53d885fcf5e11c37.ts} +4 -4
- package/test/for/components/temp/{ForIn-client-c8a1ec4473d05475e11928d06d081ab671fd9f28.ts → ForIn-client-5cc25a98e10826e8477fe6f931d5d2bbd0b13c9f.ts} +3 -2
- package/test/for/components/temp/{ForIn-server-d92cf8d3c3e300b562308607caca2c9cab3cb30b.ts → ForIn-server-d68e82c048f7e0f1525f74724b91e5cd01cdc6a6.ts} +1 -0
- package/test/for/components/temp/{ForOf-client-069881d4d9e52bc091e7213154924f3e1626174a.ts → ForOf-client-70b0d59ff72f1cffe2e0ac8523dd7ccdca4ffe39.ts} +3 -2
- package/test/for/components/temp/{ForOf-server-3bfbb33bd589890d272bbcbea53d9598f53bfd70.ts → ForOf-server-ac08d98dd249a3e64a366b8488450e6ce0d18def.ts} +1 -0
- package/test/for/for-escape.test.ts +2 -3
- package/test/function/components/output/Function-client.ts +1 -1
- package/test/function/components/temp/{Function-client-b8931e51769f3f1e84d1491c6474f8551acf9f8d.ts → Function-client-b3ff029a821d47e1a2249a52dfb681f4b2e96232.ts} +1 -1
- package/test/function/function.test.ts +1 -2
- package/test/html/components/output/Html-client.ts +3 -1
- package/test/html/components/output/Html-server.ts +1 -0
- package/test/html/components/temp/{Html-client-5fc745d9980a42a70dcb3473b0fd976e69882c9e.ts → Html-client-766ba4a63f28f929ca16cd7d1640fe92f9b30792.ts} +3 -1
- package/test/html/components/temp/{Html-server-437ea390e58947213ede74755a012cdacceeebe7.ts → Html-server-0a41da8b81bf833f331f3becdbac14be7ddc6c8c.ts} +1 -0
- package/test/if/components/output/IfAfterIf-client.ts +5 -4
- package/test/if/components/output/IfAfterIf-server.ts +1 -0
- package/test/if/components/output/IfElse-client.ts +4 -3
- package/test/if/components/output/IfElse-server.ts +1 -0
- package/test/if/components/output/IfElseIf-client.ts +5 -4
- package/test/if/components/output/IfElseIf-server.ts +1 -0
- package/test/if/components/output/IfNested-client.ts +5 -4
- package/test/if/components/output/IfNested-server.ts +1 -0
- package/test/if/components/temp/{IfAfterIf-client-a489daa5b961ed9da71418fdbb1665b6ba39f1b7.ts → IfAfterIf-client-49b6b8c42b0a351561f9f5f22c2ae2e844bf3b58.ts} +5 -4
- package/test/if/components/temp/{IfAfterIf-server-243736e666e7d77d3f8553a1682734555f5ffd22.ts → IfAfterIf-server-eb67cf1fcf6711882266219940a47bd4a66497f3.ts} +1 -0
- package/test/if/components/temp/{IfElse-client-4c71642f412d5dd2f45729eafb7e974781dbe011.ts → IfElse-client-e236d4a2e99262ff09675bc519c07e2826c0d70b.ts} +4 -3
- package/test/if/components/temp/{IfElse-server-64c055182b327504ee71d1f1d44cfccf48be350d.ts → IfElse-server-c077e0e30f4d2adec41ab779198362d21542d055.ts} +1 -0
- package/test/if/components/temp/{IfElseIf-client-98d50d6f40c2385c4ef4fc02329f9d2e182c76c4.ts → IfElseIf-client-b92106861f0c7ec3d09e3a42bb93d8f5bd4e3bdf.ts} +5 -4
- package/test/if/components/temp/{IfElseIf-server-79788b13af905175f50bfa8658f2ff2af73db232.ts → IfElseIf-server-67991eee3f56dc687cda600511c31396438e0a77.ts} +1 -0
- package/test/{build-server/components/temp/IfNested-client-979db97eea5b4595550b9b46f297f3fbc31796d2.ts → if/components/temp/IfNested-client-f563ac1b16a2280e457557281c4925ed447a9cd7.ts} +5 -4
- package/test/{build-server/components/temp/IfNested-server-3c4e4b6f2162c0906cef685830219b9ea9ee985c.ts → if/components/temp/IfNested-server-0a2a9643324ab73b02b310cad61ba87dab146ab2.ts} +1 -0
- package/test/mount/components/Mount.torp +1 -1
- package/test/mount/components/output/Mount-client.ts +0 -2
- package/test/mount/components/output/Mount-server.ts +1 -1
- package/test/mount/components/temp/{Mount-client-49d8d6475336b5749fe8a17be847fd2b6cda5ccc.ts → Mount-client-36dbc95a61345a1b7dcf07e6b0c998af2afca691.ts} +0 -2
- package/test/mount/components/temp/{Mount-server-e3d689cf52a4477da9aa00e2c7604110710db991.ts → Mount-server-8bef1924a731f3db63cb827be3938fec685e53af.ts} +1 -1
- package/test/on-mount/components/output/OnMount-client.ts +0 -2
- package/test/on-mount/components/temp/{OnMount-client-b2dfd41a0aaeafb3b7af14793a03e0fc3bc43aaa.ts → OnMount-client-21708a638d2939ee8b017f5dc819cee4748bde87.ts} +0 -2
- package/test/party/13-emit-to-parent.test.ts +2 -3
- package/test/party/16-context.test.ts +1 -2
- package/test/party/17-input-text.test.ts +2 -3
- package/test/party/18-input-checkbox.test.ts +1 -2
- package/test/party/19-input-radio.test.ts +2 -3
- package/test/party/20-input-select.test.ts +3 -4
- package/test/party/7-event-click.test.ts +1 -3
- package/test/party/9-conditional.test.ts +2 -4
- package/test/party/components/ColorSelect.torp +1 -1
- package/test/party/components/InputFocused.torp +1 -1
- package/test/party/components/InputHello.torp +1 -1
- package/test/party/components/IsAvailable.torp +1 -1
- package/test/party/components/PickPill.torp +2 -2
- package/test/party/components/output/AnswerButton-client.ts +3 -2
- package/test/party/components/output/AnswerButton-server.ts +1 -0
- package/test/party/components/output/AnswerButtonApp-client.ts +4 -4
- package/test/party/components/output/AnswerButtonApp-server.ts +1 -1
- package/test/party/components/output/ColorSelect-client.ts +1 -1
- package/test/party/components/output/Colors-client.ts +1 -1
- package/test/party/components/output/Counter-client.ts +1 -1
- package/test/party/components/output/FunnyButton-client.ts +1 -1
- package/test/party/components/output/FunnyButtonApp-client.ts +2 -2
- package/test/party/components/output/FunnyButtonApp-server.ts +1 -1
- package/test/party/components/output/InputFocused-client.ts +0 -2
- package/test/party/components/output/InputFocused-server.ts +1 -1
- package/test/party/components/output/InputHello-client.ts +1 -1
- package/test/party/components/output/IsAvailable-client.ts +1 -1
- package/test/party/components/output/PickPill-client.ts +2 -2
- package/test/party/components/output/TrafficLight-client.ts +6 -6
- package/test/party/components/output/UserProfile-client.ts +5 -4
- package/test/party/components/output/UserProfile-server.ts +1 -0
- package/test/party/components/output/UserProfileApp-client.ts +3 -2
- package/test/party/components/output/UserProfileApp-server.ts +1 -1
- package/test/party/components/output/UserProfileContext-client.ts +3 -3
- package/test/party/components/output/UserProfileContextApp-client.ts +2 -2
- package/test/party/components/output/UserProfileContextApp-server.ts +1 -1
- package/test/party/components/temp/{AnswerButton-client-243454cd7bf84c648f244b3587e60d01a0401039.ts → AnswerButton-client-c3dc7edbfff2db1ea111086002147d771ee12193.ts} +3 -2
- package/test/party/components/temp/{AnswerButton-server-938e46c1d2510ea37454854ef527e4aa64eb8e52.ts → AnswerButton-server-427442fa8cfc0a18817c2d37f9cb5cbcb3a88a05.ts} +1 -0
- package/test/party/components/temp/{AnswerButtonApp-client-34311c2e7412807867fb6267af31a341f092bf31.ts → AnswerButtonApp-client-3e0b63a6bbc1dee3e6cb715c0297cc2ce58d3e4e.ts} +4 -4
- package/test/party/components/temp/{AnswerButtonApp-server-3f5071775abea24ee8830830072c6fe465fc4e56.ts → AnswerButtonApp-server-bbc8bb739d2060ccda77ce406aa6b15d8f90b91c.ts} +1 -1
- package/test/party/components/temp/{ColorSelect-client-f9fb9fa09f4729da3226d5aaf30e84cd3cd705b5.ts → ColorSelect-client-5ffa6f9d77de967993088c9a01b9f976f3333176.ts} +1 -1
- package/test/party/components/temp/{Colors-client-f124162d1dd8f0c3d37bf96c8e5f18599ae3a682.ts → Colors-client-3dafffc5c2a72037f4419fc45d08963872a29958.ts} +1 -1
- package/test/party/components/temp/{Counter-client-c349710110b4afbf9593f20cfc40c162ed836079.ts → Counter-client-4d553521fcfc6c9a4e05dce89e70b2ecf8785c4e.ts} +1 -1
- package/test/party/components/temp/{FunnyButton-client-2e6bec8259065b5bc9ae16d1ca93dd1bd0c56b7c.ts → FunnyButton-client-45f2c5dd56f2cdb80102193a978df6b0cec822ab.ts} +1 -1
- package/test/party/components/temp/{FunnyButtonApp-client-4ed0ebf5be13ddb62d9942bac7f4b8a885ec6c50.ts → FunnyButtonApp-client-ac7101af922dc6ba472b75a428f340caca6be74a.ts} +2 -2
- package/test/party/components/temp/{FunnyButtonApp-server-9748c9096848e643c91237c46ea09d23f1b3fa7c.ts → FunnyButtonApp-server-f1a98a946e0bb9d1bb76b01e26d6ead8f55d32bb.ts} +1 -1
- package/test/party/components/temp/{InputFocused-client-a543f82c8db205fb3e33c62de699cff43c668a68.ts → InputFocused-client-11a9cb08909b26945bbc2451ab4c1dac09e6d113.ts} +0 -2
- package/test/party/components/temp/{InputFocused-server-222f2fa7029d1cd6941a3777293a9b2d37b7295e.ts → InputFocused-server-82be1a63c80d1dd3f06efaf0bef349d58cf1d9af.ts} +1 -1
- package/test/party/components/temp/{InputHello-client-9953499de5778bb1d8aac7691129210a6098db07.ts → InputHello-client-b0453caeae0d43dc1878039c6b49318d12624d48.ts} +1 -1
- package/test/party/components/temp/{IsAvailable-client-929ed6c872e72b6c5243b882c6a9a0d13f6a7c47.ts → IsAvailable-client-d789346a68b26fd3f5d9f7aebc4c7bd181c47cad.ts} +1 -1
- package/test/party/components/temp/{PickPill-client-f9a50a75ce63ec2ee3ac34e378e20602b93629f7.ts → PickPill-client-b47d371ae5f41d87c96b3cdeed0a8bc06fbfa9c7.ts} +2 -2
- package/test/party/components/temp/{TrafficLight-client-81dd9bd9f3332533e01f6c9b271c15e5f76e1fdb.ts → TrafficLight-client-549f9fe3418c113fb240cfa17e09c42e1e7f346a.ts} +6 -6
- package/test/party/components/temp/{UserProfile-client-938bcef20a2555de22aca939022a32742ac5e729.ts → UserProfile-client-2c13aac1ad915e51dc557f9af765669e636c0fea.ts} +5 -4
- package/test/party/components/temp/{UserProfile-server-9df5c59b8797fa67c479bc76450104d45e6076f9.ts → UserProfile-server-cc1162a4297f6163bfb86e7a8aeea08e8c0625c6.ts} +1 -0
- package/test/party/components/temp/{UserProfileApp-client-af27173415d65647cab0f30a9a4967cef0307e25.ts → UserProfileApp-client-2be7a11319cca4d7bfa0f3d2205c441d7e203780.ts} +3 -2
- package/test/party/components/temp/{UserProfileApp-server-6a7dbe68ee8041785cef50fb15a9e5ba475e120f.ts → UserProfileApp-server-ab9ff66f787f775aa8571314fee8bcbef85489ef.ts} +1 -1
- package/test/party/components/temp/{UserProfileContext-client-93211cdba795b8baf926f60f5b17da90701743b3.ts → UserProfileContext-client-2aa36f436a5f20614d77f48963ec5ca442eebd90.ts} +3 -3
- package/test/party/components/temp/{UserProfileContextApp-client-7ea7d90a35894408757aef3e935d3a8badf93aea.ts → UserProfileContextApp-client-5099052fdcd8fb4c368c45090390947424a4e9b0.ts} +2 -2
- package/test/party/components/temp/{UserProfileContextApp-server-90290c770529d7211eabf29e7d0fe868aa856b52.ts → UserProfileContextApp-server-6be8dab2ed4f8911f26bef137e7dea164f2b894d.ts} +1 -1
- package/test/props/components/Reactive.torp +18 -0
- package/test/props/components/output/Reactive-client.ts +70 -0
- package/test/props/components/output/Reactive-server.ts +40 -0
- package/test/props/components/temp/Reactive-client-e3e5f6ee2f22c46337c6ab1df2f241133c7e2646.ts +70 -0
- package/test/props/components/temp/Reactive-server-0914d91287a1bc6d32d7cc56d086624762dbfc04.ts +40 -0
- package/test/props/reactive.test.ts +40 -0
- package/test/replace/components/output/Replace-client.ts +3 -2
- package/test/replace/components/output/Replace-server.ts +1 -0
- package/test/replace/components/temp/{Replace-client-ea4ddc73c71181fb6ef3c6f5bf61b0b9e017f00a.ts → Replace-client-3fdab63871fa4bb792317caefd3539b1888325b1.ts} +3 -2
- package/test/replace/components/temp/{Replace-server-30eb1ad796516fa4d310798a9c8a6811ec13cbd9.ts → Replace-server-857aca7a58deffc3a1c95ab9d31628b4051ca203.ts} +1 -0
- package/test/slots/components/output/Article-client.ts +2 -2
- package/test/slots/components/output/Basic-client.ts +1 -1
- package/test/slots/components/output/Basic-server.ts +1 -1
- package/test/slots/components/output/Let-client.ts +4 -3
- package/test/slots/components/output/Let-server.ts +2 -1
- package/test/slots/components/output/List-client.ts +1 -1
- package/test/slots/components/output/List-server.ts +1 -0
- package/test/slots/components/output/Named-client.ts +2 -2
- package/test/slots/components/output/Named-server.ts +1 -1
- package/test/slots/components/output/Unused-client.ts +1 -1
- package/test/slots/components/output/Unused-server.ts +1 -1
- package/test/slots/components/temp/{Article-client-741f94eab2e96655f4c9d69ccd7d9c7cc998f4ce.ts → Article-client-80848d6cadd8abac61865d14ddd35685844797e0.ts} +2 -2
- package/test/slots/components/temp/{Basic-client-c82bc3c5e10f2f2c1869347435262c8f3039e32f.ts → Basic-client-97b18686412869e8c814fd4542dfe826b1f7669f.ts} +1 -1
- package/test/slots/components/temp/{Basic-server-21fb4f8caa3bbcae219aaef388af8c26c46fa5ce.ts → Basic-server-248392e2cd147b537cd44e9a5a71885ef20102e4.ts} +1 -1
- package/test/slots/components/temp/{Let-client-c54696fd1b5b859a693744722957fa960f72fad6.ts → Let-client-be69c1f5aa32faf16239050d7836db46cfdcba2f.ts} +4 -3
- package/test/slots/components/temp/{Let-server-4d78ffc8741fa737f2cd915b36c0e6ec88a9146f.ts → Let-server-c3293219ed27aec61a6af36d451ddf6609c40027.ts} +2 -1
- package/test/slots/components/temp/{List-client-0659d999cfb48b865fe5b8aaaf2a4ddac3a8a8b6.ts → List-client-a829b33214de829de689a72d2e8703b2266ad7a4.ts} +1 -1
- package/test/slots/components/temp/{List-server-4b76485a259d054187edad8aa691d80ac918ad86.ts → List-server-06503834c9bfae9b8c2b61742568b020a3de961c.ts} +1 -0
- package/test/slots/components/temp/{Named-client-0626b2f0911f77f5edcfda82f9751bcbc37b7641.ts → Named-client-2d9d88f5fdf74d81c3ed1d769a476f4ac36c8b99.ts} +2 -2
- package/test/slots/components/temp/{Named-server-e802f901223d697c7fd0a1a234ce1930af1b4b3f.ts → Named-server-65a7bbf038111475c8f07dccb34040ab8c1392c4.ts} +1 -1
- package/test/slots/components/temp/{Unused-client-aa05465731e0d00e18189498f49c94f991e76f10.ts → Unused-client-1b16491cb800bbbbd871d9fbf5966c7275244019.ts} +1 -1
- package/test/slots/components/temp/{Unused-server-00b92d14665a565f0042b1f56231f28bc38a1252.ts → Unused-server-e5d1e85116bebc7e1a2882cb8f2c9ae7975a1de7.ts} +1 -1
- package/test/special-component/components/output/Component-client.ts +5 -4
- package/test/special-component/components/output/Component-server.ts +3 -2
- package/test/special-component/components/temp/{Component-client-3cc84b23def8830b8ef441bde0f03b3e9718196a.ts → Component-client-22f7e1d0955fb3d90939e956a1f0f77118c259b6.ts} +5 -4
- package/test/special-component/components/temp/{Component-server-5dc597784ea1fe45ac2cfb21305cf2187a3868e8.ts → Component-server-ce596cd84dc11f67c9f0588060a5b672eddf9715.ts} +3 -2
- package/test/special-element/components/output/Element-client.ts +2 -1
- package/test/special-element/components/output/Element-server.ts +1 -0
- package/test/special-element/components/temp/{Element-client-0ab8992a8e914c7e190cddac790585fef9be1c9f.ts → Element-client-21c92c04579b1d29e8813265a10897d069aad5c5.ts} +2 -1
- package/test/special-element/components/temp/{Element-server-ddb0170df4a3f369577ca7e9768e5fe799f14dfb.ts → Element-server-4bed9653529f39e72754126147fe8618f328853a.ts} +1 -0
- package/test/special-self/components/output/Self-client.ts +3 -2
- package/test/special-self/components/output/Self-server.ts +1 -0
- package/test/special-self/components/temp/{Self-client-3982f174954034643c4d17cfc66d7f10bf1d4df6.ts → Self-client-911c67194be1fdd997537310bcafe712161e8251.ts} +3 -2
- package/test/special-self/components/temp/{Self-server-97ffbdaae47f4463034e1d318a8073d078ff138f.ts → Self-server-49ba9be1f6255dd4daf490c640f5222a85960218.ts} +1 -0
- package/test/style/components/output/Style-client.ts +2 -1
- package/test/style/components/output/Style-server.ts +1 -0
- package/test/style/components/temp/{Style-client-085517e82bdd015c86f4c2577447c6a2791cf656.ts → Style-client-cbfac1e255c33a867ccbd5f9d1484a855d91a2d7.ts} +2 -1
- package/test/style/components/temp/{Style-server-b2615163fbafdcb2a5d4155120edf2f66ef3bba6.ts → Style-server-763d82ee2296be3f7620814aed950b505329c04c.ts} +1 -0
- package/test/svg/components/output/Shape-client.ts +4 -3
- package/test/svg/components/output/Shape-server.ts +1 -0
- package/test/svg/components/temp/{Shape-client-ea698ed1b7d0c3615adff35fa4956f22840f5fda.ts → Shape-client-cb98b36ab2a0d9f06b484a3c988fb43c3a71a4a0.ts} +4 -3
- package/test/svg/components/temp/{Shape-server-eb32049cfb7c058b2c4079c5f86ef00651ff6d69.ts → Shape-server-500d7fe4556026234ce5379b8e90595ddd094edc.ts} +1 -0
- package/test/switch/components/output/Switch-client.ts +5 -4
- package/test/switch/components/output/Switch-server.ts +1 -0
- package/test/switch/components/temp/{Switch-client-4c4adac7308795807517e66bc268a38f87df6bda.ts → Switch-client-9980de45e3346b79525c445edec7cbc3b375e8a4.ts} +5 -4
- package/test/switch/components/temp/{Switch-server-21fcac2b02c6071136bb0dc394babd27e454d2c9.ts → Switch-server-1c5690726f28008bb565966af69b6e4e019dea82.ts} +1 -0
- package/test/text/components/output/Text-client.ts +3 -2
- package/test/text/components/output/Text-server.ts +1 -0
- package/test/text/components/temp/{Text-client-9840092be1b4552ddce6e5efc2f1b395637a0a3d.ts → Text-client-63f1d3bf9b3bd145c7ce7058716640e27144055e.ts} +3 -2
- package/test/text/components/temp/{Text-server-6774aa9d4ccce941224ba0a8fb1d3e42eb31807e.ts → Text-server-9d3dd6f51e893e63c1999ceafce19ca1697d76ea.ts} +1 -0
- package/test/watch-array/components/output/Array-client.ts +4 -3
- package/test/watch-array/components/output/Array-server.ts +1 -0
- package/test/watch-array/components/output/ArrayEntries-client.ts +4 -3
- package/test/watch-array/components/output/ArrayEntries-server.ts +1 -0
- package/test/watch-array/components/output/ArrayIndexes-client.ts +4 -3
- package/test/watch-array/components/output/ArrayIndexes-server.ts +1 -0
- package/test/watch-array/components/output/ArrayUnkeyed-client.ts +4 -3
- package/test/watch-array/components/output/ArrayUnkeyed-server.ts +1 -0
- package/test/watch-array/components/temp/{Array-client-b29a42f88c2a2f37b3a86bdb9535e20a487887e1.ts → Array-client-ffd82188a45877d74053c82fb3616e4aed0fc2ad.ts} +4 -3
- package/test/watch-array/components/temp/{Array-server-ced54fc7e63196f9c24c2e55b27bfe6cf7821dcb.ts → Array-server-3715e815af887e8487b214e7de324850fe99e312.ts} +1 -0
- package/test/watch-array/components/temp/{ArrayEntries-client-6289890758b1f6b462a74417e0b9e2e46d946ccd.ts → ArrayEntries-client-b6e982660628576061dbb44539e970b9549bdcfa.ts} +4 -3
- package/test/watch-array/components/temp/{ArrayEntries-server-0429a18ffbe39afe87612889a3010c3fcaa601dc.ts → ArrayEntries-server-85cbe80fbb7f6885287825e2cc0dfc1cb9835d79.ts} +1 -0
- package/test/watch-array/components/temp/{ArrayIndexes-client-fe4b1c49f442b3e5411f331c52ae6c5ab38f2b2d.ts → ArrayIndexes-client-39337aa43bd8c10a53db836c3be233d48dd39b91.ts} +4 -3
- package/test/watch-array/components/temp/{ArrayIndexes-server-20c01f10832f035b007f85a423778934d51a703a.ts → ArrayIndexes-server-ec623c724af0c7212675d61ea68e9dee87f96caa.ts} +1 -0
- package/test/watch-array/components/temp/{ArrayUnkeyed-client-3fffe2ce749ee84e0730130bfd730d432e3c4e12.ts → ArrayUnkeyed-client-7606f9a6a221c8cf6a8b51e4895d10a3d7bccc11.ts} +4 -3
- package/test/watch-array/components/temp/{ArrayUnkeyed-server-0ab804a5e7bf5b47594d85adab79735e89a3939d.ts → ArrayUnkeyed-server-db21cd576a4c70973abe10f6c8ef5cecb3ead86c.ts} +1 -0
- package/test/watch-object/components/output/Watched-client.ts +2 -1
- package/test/watch-object/components/output/Watched-server.ts +1 -0
- package/test/watch-object/components/temp/{Watched-client-cb293038cd0a39043d05639c624a17d512419c25.ts → Watched-client-bbffbf2cede1a5c071b770670eb39c0f0be725af.ts} +2 -1
- package/test/watch-object/components/temp/{Watched-server-4884585cf4f50493a70631909f2230153531208e.ts → Watched-server-0252addaf92fb0f0c1e2937f42918a1c9f31d196.ts} +1 -0
- package/src/render/flushMountEffects.ts +0 -8
- package/test/if/components/temp/IfNested-client-979db97eea5b4595550b9b46f297f3fbc31796d2.ts +0 -90
- package/test/if/components/temp/IfNested-server-3c4e4b6f2162c0906cef685830219b9ea9ee985c.ts +0 -30
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@torpor/view",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Torpor's view library, for writing and mounting components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"@testing-library/user-event": "^14.6.1",
|
|
36
36
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
|
37
37
|
"@types/jsdom": "^21.1.7",
|
|
38
|
-
"@types/node": "^22.15.
|
|
38
|
+
"@types/node": "^22.15.29",
|
|
39
39
|
"fast-glob": "^3.3.3",
|
|
40
40
|
"jsdom": "^26.1.0",
|
|
41
41
|
"sucrase": "^3.35.0",
|
|
42
42
|
"tinybench": "^4.0.1",
|
|
43
|
-
"tsup": "^8.
|
|
43
|
+
"tsup": "^8.5.0",
|
|
44
44
|
"tsx": "^4.19.4",
|
|
45
45
|
"typescript": "^5.8.3",
|
|
46
|
-
"vitest": "^3.1
|
|
46
|
+
"vitest": "^3.2.1"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsc --noEmit && tsup && tsx ./scripts/copyToRepl.ts",
|
package/scripts/copyToRepl.ts
CHANGED
|
@@ -27,7 +27,7 @@ async function run() {
|
|
|
27
27
|
.replaceAll(/^import ".\/chunk-(.+?).js";/gms, "")
|
|
28
28
|
.replaceAll(/\/\/# sourceMappingURL=(.+?).js.map/g, "");
|
|
29
29
|
|
|
30
|
-
const destFile = "../../site/src/
|
|
30
|
+
const destFile = "../../site/src/views/repl/view.txt";
|
|
31
31
|
await fs.writeFile(destFile, source);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -10,7 +10,6 @@ const importsMap: Record<string, string> = {
|
|
|
10
10
|
$unwrap: 'import { $unwrap } from "${folder}";',
|
|
11
11
|
$run: 'import { $run } from "${folder}";',
|
|
12
12
|
$mount: 'import { $mount } from "${folder}";',
|
|
13
|
-
t_flush: 'import { t_flush } from "${folder}";',
|
|
14
13
|
t_range: 'import { t_range } from "${folder}";',
|
|
15
14
|
t_push_range: 'import { t_push_range } from "${folder}";',
|
|
16
15
|
t_pop_range: 'import { t_pop_range } from "${folder}";',
|
|
@@ -96,7 +95,8 @@ function buildTemplate(template: Template, imports: Set<string>, b: Builder) {
|
|
|
96
95
|
|
|
97
96
|
// Make sure we've got $props if we're going to be using it
|
|
98
97
|
if (current.props?.length) {
|
|
99
|
-
|
|
98
|
+
imports.add("$watch");
|
|
99
|
+
b.append(`$props ??= $watch({});`);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// Redefine $context so that any newly added properties will only be passed to children
|
|
@@ -139,15 +139,6 @@ function buildTemplate(template: Template, imports: Set<string>, b: Builder) {
|
|
|
139
139
|
currentIndex += 1;
|
|
140
140
|
current = template.components[currentIndex];
|
|
141
141
|
|
|
142
|
-
// TODO: Only if the component has $mount
|
|
143
|
-
// Flush any $mount calls that were encountered -- move this to
|
|
144
|
-
// addFragment, because we also have to flush events and animations
|
|
145
|
-
if (imports.has("$mount")) {
|
|
146
|
-
imports.add("t_flush");
|
|
147
|
-
b.append("");
|
|
148
|
-
b.append("t_flush();");
|
|
149
|
-
}
|
|
150
|
-
|
|
151
142
|
marker = i + "/* @end */".length;
|
|
152
143
|
}
|
|
153
144
|
}
|
|
@@ -25,17 +25,33 @@ export default function buildComponentNode(
|
|
|
25
25
|
const componentHasProps = node.attributes.length || root;
|
|
26
26
|
const propsName = componentHasProps ? nextVarName("props", status) : "undefined";
|
|
27
27
|
if (componentHasProps) {
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
|
|
28
|
+
// NOTE: The $props object is wrapped in a proxy so that components can
|
|
29
|
+
// be updated if they refer to a $props.property in e.g. an element's
|
|
30
|
+
// attribute
|
|
31
|
+
// TODO: default props etc
|
|
32
|
+
status.imports.add("$watch");
|
|
33
|
+
b.append(`const ${propsName}: any = $watch({});`);
|
|
34
|
+
|
|
32
35
|
for (let { name, value } of node.attributes) {
|
|
33
36
|
if (name === "self" && node.tagName === ":component") {
|
|
34
37
|
// Ignore this special attribute
|
|
35
38
|
} else if (name.startsWith("{") && name.endsWith("}")) {
|
|
36
39
|
// It's a shortcut attribute
|
|
40
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
41
|
+
// in either case we set the value of the width property
|
|
37
42
|
name = name.substring(1, name.length - 1);
|
|
38
|
-
|
|
43
|
+
const propName = name.split(".").at(-1);
|
|
44
|
+
buildRun("setProp", `${propsName}["${propName}"] = ${name};`, status, b);
|
|
45
|
+
} else if (name.startsWith("&") && value != null && isFullyReactive(value)) {
|
|
46
|
+
// It's a bound property
|
|
47
|
+
// Add two $runs -- one to update the props, and one to update the value
|
|
48
|
+
// The component author will need to make sure $props.x is updated
|
|
49
|
+
// TODO: Maybe allow adding a Bindable<T> type to the $props interface??
|
|
50
|
+
// e.g. Component($props: { text: Bindable<string> })
|
|
51
|
+
name = name.substring(1);
|
|
52
|
+
value = value.substring(1, value.length - 1);
|
|
53
|
+
buildRun("setProp", `${propsName}["${name}"] = ${value};`, status, b);
|
|
54
|
+
buildRun("setBinding", `${value} = ${propsName}["${name}"];`, status, b);
|
|
39
55
|
} else if (value != null) {
|
|
40
56
|
let fullyReactive = isFullyReactive(value);
|
|
41
57
|
let partlyReactive = isReactive(value);
|
|
@@ -139,8 +139,11 @@ function buildHeadNode(node: ElementNode, status: BuildStatus, b: Builder) {
|
|
|
139
139
|
for (let { name, value } of node.attributes) {
|
|
140
140
|
if (name.startsWith("{") && name.endsWith("}")) {
|
|
141
141
|
// It's a shortcut attribute
|
|
142
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
143
|
+
// in either case we set the value of the width property
|
|
142
144
|
name = name.substring(1, name.length - 1);
|
|
143
|
-
|
|
145
|
+
const propName = name.split(".").at(-1);
|
|
146
|
+
buildRun("setAttribute", `t_head_el.setAttribute("${propName}", ${name});`, status, b);
|
|
144
147
|
} else if (value != null && isReactive(value)) {
|
|
145
148
|
// It's a reactive attribute
|
|
146
149
|
if (isFullyReactive(value)) {
|
|
@@ -170,13 +173,30 @@ function buildElementAttributes(
|
|
|
170
173
|
// TODO: Flatten this out
|
|
171
174
|
// TODO: Add an error if any reactive attributes are used non-reactively
|
|
172
175
|
|
|
176
|
+
// Do &ref first, just in case any other attributes depend on it being set
|
|
177
|
+
// e.g. if you have a `style` attribute that depends on the element's size
|
|
178
|
+
const refAttribute = node.attributes.find((a) => a.name === "&ref");
|
|
179
|
+
if (refAttribute) {
|
|
180
|
+
let value = refAttribute.value;
|
|
181
|
+
if (value != null && isFullyReactive(value)) {
|
|
182
|
+
// Bind the DOM element to a user-defined variable
|
|
183
|
+
value = value.substring(1, value.length - 1);
|
|
184
|
+
b.append(`${value} = ${varName};`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
173
188
|
for (let { name, value } of node.attributes) {
|
|
174
189
|
if (name === "self" && node.tagName === ":element") {
|
|
175
190
|
// Ignore this special attribute
|
|
191
|
+
} else if (name === "&ref") {
|
|
192
|
+
// Ignore this one, it should have been done already, above
|
|
176
193
|
} else if (name.startsWith("{") && name.endsWith("}")) {
|
|
177
194
|
// It's a shortcut attribute
|
|
195
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
196
|
+
// in either case we set the value of the width property
|
|
178
197
|
name = name.substring(1, name.length - 1);
|
|
179
|
-
|
|
198
|
+
const propName = name.split(".").at(-1);
|
|
199
|
+
buildRun("setAttribute", `${varName}.setAttribute("${propName}", ${name});`, status, b);
|
|
180
200
|
} else if (value != null && isReactive(value)) {
|
|
181
201
|
// It's a reactive attribute
|
|
182
202
|
if (isFullyReactive(value)) {
|
|
@@ -185,17 +205,14 @@ function buildElementAttributes(
|
|
|
185
205
|
value = `\`${trimQuotes(value).replaceAll("{", "${")}\``;
|
|
186
206
|
}
|
|
187
207
|
|
|
188
|
-
if (name === "
|
|
189
|
-
// Bind the DOM element to a user-defined variable
|
|
190
|
-
b.append(`${value} = ${varName};`);
|
|
191
|
-
} else if (name === ":group") {
|
|
208
|
+
if (name === "&group") {
|
|
192
209
|
buildBindGroupAttribute(node, varName, value, status, b);
|
|
193
|
-
} else if (name === "
|
|
210
|
+
} else if (name === "&value" || name === "&checked") {
|
|
194
211
|
buildBindAttribute(node, varName, name, value, status, b);
|
|
195
212
|
} else if (name === ":onmount") {
|
|
196
|
-
// The :onmount event is faked by us by creating a $
|
|
197
|
-
// means that you can have unmount functionality by
|
|
198
|
-
// cleanup function
|
|
213
|
+
// The :onmount event is faked by us by creating a $mount. This
|
|
214
|
+
// also means that you can have unmount functionality by
|
|
215
|
+
// returning a cleanup function
|
|
199
216
|
buildMount("elMount", `return (${trimEnd(value.trim(), ";")})(${varName});`, status, b);
|
|
200
217
|
} else if (name.startsWith("on")) {
|
|
201
218
|
buildEventAttribute(varName, name, value, status, b);
|
|
@@ -696,12 +696,38 @@ function getFragmentVarPath(
|
|
|
696
696
|
if (name !== "?") {
|
|
697
697
|
// Add the path, so that we can shorten subsequent paths e.g.
|
|
698
698
|
// const div = t_next(t_child(root));
|
|
699
|
-
// const p = t_next(t_next(t_next(t_child(root))))
|
|
699
|
+
// const p = t_next(t_next(t_next(t_child(root))))
|
|
700
|
+
// => const p = t_next(t_next(div))
|
|
700
701
|
varPaths.set(varPath, name);
|
|
701
702
|
// Add the name, so that we are always using the last declared name
|
|
702
703
|
varPaths.set(name, name);
|
|
703
704
|
}
|
|
704
705
|
|
|
706
|
+
// Shorten `t_next(t_next(x))` to `t_next(x, 2)`
|
|
707
|
+
while (varPath.includes("t_next(t_next(")) {
|
|
708
|
+
const match = varPath.match(/(t_next\(){2,}/)![0];
|
|
709
|
+
const count = match.length / "t_next(".length;
|
|
710
|
+
const pos = varPath.indexOf("t_next(t_next(");
|
|
711
|
+
const head = varPath.substring(0, pos);
|
|
712
|
+
let level = 0;
|
|
713
|
+
let end = 0;
|
|
714
|
+
for (let i = pos + match.length; i < varPath.length; i++) {
|
|
715
|
+
if (varPath[i] === "(") {
|
|
716
|
+
level++;
|
|
717
|
+
} else if (varPath[i] === ")") {
|
|
718
|
+
if (level === 0) {
|
|
719
|
+
end = i;
|
|
720
|
+
break;
|
|
721
|
+
} else {
|
|
722
|
+
level--;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
const tail = varPath.substring(end + count);
|
|
727
|
+
const param = varPath.substring(pos + match.length, end);
|
|
728
|
+
varPath = `${head}t_next(${param}, ${count})${tail}`;
|
|
729
|
+
}
|
|
730
|
+
|
|
705
731
|
return varPath;
|
|
706
732
|
}
|
|
707
733
|
|
|
@@ -721,7 +747,17 @@ function getFragmentVarPathPart(
|
|
|
721
747
|
for (let [i, child] of path.children.entries()) {
|
|
722
748
|
if (i > 0) {
|
|
723
749
|
status.imports.add("t_next");
|
|
750
|
+
//if (varPath.startsWith("t_next")) {
|
|
751
|
+
// const match = varPath.match(/t_next\(.+?, (\d+)\)/);
|
|
752
|
+
// if (match) {
|
|
753
|
+
// const count = parseInt(match[1]) + 1;
|
|
754
|
+
// varPath = varPath.replace(/t_next\((.+), \d+\)/, `t_next($1, ${count})`);
|
|
755
|
+
// } else {
|
|
756
|
+
// varPath = varPath.replace(/t_next\((.+)\)/, `t_next($1, 2)`);
|
|
757
|
+
// }
|
|
758
|
+
//} else {
|
|
724
759
|
varPath = `t_next(${varPath})`;
|
|
760
|
+
//}
|
|
725
761
|
}
|
|
726
762
|
|
|
727
763
|
if (i === path.children.length - 1 && child.children.length) {
|
|
@@ -27,8 +27,11 @@ export default function buildSlotNode(node: ElementNode, status: BuildStatus, b:
|
|
|
27
27
|
for (let { name, value } of slotAttributes) {
|
|
28
28
|
if (name.startsWith("{") && name.endsWith("}")) {
|
|
29
29
|
// It's a shortcut attribute
|
|
30
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
31
|
+
// in either case we set the value of the width property
|
|
30
32
|
name = name.substring(1, name.length - 1);
|
|
31
|
-
|
|
33
|
+
const propName = name.split(".").at(-1);
|
|
34
|
+
buildRun("setProp", `${propsName}["${propName}"] = ${name};`, status, b);
|
|
32
35
|
} else if (value != null) {
|
|
33
36
|
let fullyReactive = isFullyReactive(value);
|
|
34
37
|
let partlyReactive = isReactive(value);
|
|
@@ -29,8 +29,11 @@ export default function buildServerComponentNode(
|
|
|
29
29
|
for (let { name, value } of node.attributes) {
|
|
30
30
|
if (name.startsWith("{") && name.endsWith("}")) {
|
|
31
31
|
// It's a shortcut attribute
|
|
32
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
33
|
+
// in either case we set the value of the width property
|
|
32
34
|
name = name.substring(1, name.length - 1);
|
|
33
|
-
|
|
35
|
+
const propName = name.split(".").at(-1);
|
|
36
|
+
b.append(`${propsName}["${propName}"] = ${name};`);
|
|
34
37
|
} else if (value != null) {
|
|
35
38
|
let fullyReactive = isFullyReactive(value);
|
|
36
39
|
let partlyReactive = isReactive(value);
|
|
@@ -63,14 +63,17 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
|
|
|
63
63
|
);
|
|
64
64
|
} else if (name.startsWith("{") && name.endsWith("}")) {
|
|
65
65
|
// It's a shortcut attribute
|
|
66
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
67
|
+
// in either case we set the value of the width property
|
|
66
68
|
name = name.substring(1, name.length - 1);
|
|
69
|
+
const propName = name.split(".").at(-1);
|
|
67
70
|
status.imports.add("t_attr");
|
|
68
|
-
attributes.push(`${
|
|
71
|
+
attributes.push(`${propName}="\${t_attr(${name})}"`);
|
|
69
72
|
} else if (value != null && isFullyReactive(value)) {
|
|
70
73
|
// It's a reactive attribute
|
|
71
74
|
value = value.substring(1, value.length - 1);
|
|
72
75
|
|
|
73
|
-
if (name === "
|
|
76
|
+
if (name === "&ref" || name === "&value" || name === "&checked" || name === "&group") {
|
|
74
77
|
let defaultValue = "";
|
|
75
78
|
let typeAttribute = node.attributes.find((a) => a.name === "type");
|
|
76
79
|
if (typeAttribute && typeAttribute.value) {
|
|
@@ -41,8 +41,11 @@ export default function buildServerSlotNode(
|
|
|
41
41
|
for (let { name, value } of slotAttributes) {
|
|
42
42
|
if (name.startsWith("{") && name.endsWith("}")) {
|
|
43
43
|
// It's a shortcut attribute
|
|
44
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
45
|
+
// in either case we set the value of the width property
|
|
44
46
|
name = name.substring(1, name.length - 1);
|
|
45
|
-
|
|
47
|
+
const propName = name.split(".").at(-1);
|
|
48
|
+
b.append(`${propsName}["${propName}"] = ${name};`);
|
|
46
49
|
} else if (value != null) {
|
|
47
50
|
let fullyReactive = isFullyReactive(value);
|
|
48
51
|
let partlyReactive = isReactive(value);
|
|
@@ -35,23 +35,31 @@ export default function parseCode(source: string): ParseResult {
|
|
|
35
35
|
}
|
|
36
36
|
} else if (accept("function", status)) {
|
|
37
37
|
// If the function name starts with a capital, parse it as a component
|
|
38
|
-
consumeSpace(status)
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
if (consumeSpace(status)) {
|
|
39
|
+
if (/[A-Z]/.test(source[status.i])) {
|
|
40
|
+
parseComponentStart(status);
|
|
41
|
+
} else {
|
|
42
|
+
// Unconsume the last space
|
|
43
|
+
status.i--;
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
} else if (accept("const", status)) {
|
|
43
47
|
// If it's a function and its name starts with a capital, parse it as a component
|
|
44
|
-
consumeSpace(status)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
consumeSpace(status);
|
|
49
|
-
if (accept("=", status)) {
|
|
48
|
+
if (consumeSpace(status)) {
|
|
49
|
+
if (/[A-Z]/.test(source[status.i])) {
|
|
50
|
+
const start = status.i;
|
|
51
|
+
consumeAlphaNumeric(status);
|
|
50
52
|
consumeSpace(status);
|
|
51
|
-
if (accept("
|
|
52
|
-
status
|
|
53
|
-
|
|
53
|
+
if (accept("=", status)) {
|
|
54
|
+
consumeSpace(status);
|
|
55
|
+
if (accept("(", status, false)) {
|
|
56
|
+
status.i = start;
|
|
57
|
+
parseComponentStart(status);
|
|
58
|
+
}
|
|
54
59
|
}
|
|
60
|
+
} else {
|
|
61
|
+
// Unconsume the last space
|
|
62
|
+
status.i--;
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
} else if (accept("export", status)) {
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,6 @@ import t_animate from "./render/addAnimation";
|
|
|
6
6
|
import t_event from "./render/addEvent";
|
|
7
7
|
import t_add_fragment from "./render/addFragment";
|
|
8
8
|
import t_apply_props from "./render/applyProps";
|
|
9
|
-
import t_flush from "./render/flushMountEffects";
|
|
10
9
|
import t_fmt from "./render/formatText";
|
|
11
10
|
import t_class from "./render/getClasses";
|
|
12
11
|
import t_fragment from "./render/getFragment";
|
|
@@ -44,7 +43,6 @@ export {
|
|
|
44
43
|
t_event,
|
|
45
44
|
t_add_fragment,
|
|
46
45
|
t_apply_props,
|
|
47
|
-
t_flush,
|
|
48
46
|
t_fmt,
|
|
49
47
|
t_class,
|
|
50
48
|
t_fragment,
|
package/src/motion/animate.ts
CHANGED
|
@@ -18,13 +18,13 @@ export default async function animate(
|
|
|
18
18
|
// - store the animation
|
|
19
19
|
// - reverse it if it's running and the range appears/disappears
|
|
20
20
|
// - transfer the animation to the new element
|
|
21
|
-
|
|
22
21
|
let animationOptions = Object.assign(
|
|
23
22
|
{
|
|
24
23
|
direction: enter ? "normal" : "reverse",
|
|
25
|
-
// TODO: Should probably have a global setting for
|
|
24
|
+
// TODO: Should probably have a global setting for these somewhere
|
|
26
25
|
// And respect browser reduce motion settings
|
|
27
|
-
duration:
|
|
26
|
+
duration: 300,
|
|
27
|
+
easing: "ease-in-out",
|
|
28
28
|
fill: "forwards",
|
|
29
29
|
},
|
|
30
30
|
options,
|
|
@@ -32,9 +32,13 @@ export default async function animate(
|
|
|
32
32
|
|
|
33
33
|
const animation = el.animate(keyframes, animationOptions);
|
|
34
34
|
|
|
35
|
-
// HACK: I'm not entirely sure why
|
|
36
|
-
// animations never start
|
|
37
|
-
|
|
35
|
+
// HACK: I'm not entirely sure why we need to sent the animation's timeline,
|
|
36
|
+
// but without it, animations never start
|
|
37
|
+
// HACK: We also need to make sure the element has been added to the DOM
|
|
38
|
+
// with a timeout
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
animation.timeline = el.ownerDocument.timeline;
|
|
41
|
+
}, 1);
|
|
38
42
|
|
|
39
43
|
// Add the animation to the active range, so that the range won't be cleared
|
|
40
44
|
// until the animation is completed
|
package/src/render/$unwrap.ts
CHANGED
|
@@ -6,5 +6,5 @@ import { proxyDataSymbol } from "../watch/symbols";
|
|
|
6
6
|
* @param object The proxy object
|
|
7
7
|
*/
|
|
8
8
|
export default function $unwrap<T extends Record<PropertyKey, any>>(object: T): T {
|
|
9
|
-
return object[proxyDataSymbol].target || object;
|
|
9
|
+
return object && object[proxyDataSymbol] ? object[proxyDataSymbol].target || object : object;
|
|
10
10
|
}
|
|
@@ -40,12 +40,20 @@ export default function addFragment(
|
|
|
40
40
|
parent.insertBefore(fragment, before);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// If we're adding this fragment to the DOM, we can now
|
|
44
|
-
// events and play our stashed animations
|
|
43
|
+
// If we're adding this fragment to the DOM, we can now run any $mount
|
|
44
|
+
// effects, add our stashed events and play our stashed animations
|
|
45
45
|
if (!parentIsFragment) {
|
|
46
|
-
//
|
|
47
|
-
//
|
|
46
|
+
// Only run $mount effects if not hydrating (if hydrating, they will get
|
|
47
|
+
// run at the end when everything is hooked up)
|
|
48
|
+
if (!context.hydrationNode) {
|
|
49
|
+
for (let effect of context.mountEffects) {
|
|
50
|
+
$run(effect);
|
|
51
|
+
}
|
|
52
|
+
context.mountEffects.length = 0;
|
|
53
|
+
}
|
|
48
54
|
|
|
55
|
+
// Set the active range for each event so it will get attached to the
|
|
56
|
+
// right one and set it back afterwards
|
|
49
57
|
for (let event of context.stashedEvents) {
|
|
50
58
|
context.activeRange = event.range;
|
|
51
59
|
$run(function addFragmentEvent() {
|
|
@@ -57,6 +65,8 @@ export default function addFragment(
|
|
|
57
65
|
}
|
|
58
66
|
context.stashedEvents.length = 0;
|
|
59
67
|
|
|
68
|
+
// Set the active range for each animation so it will get attached to
|
|
69
|
+
// the right one and set it back afterwards
|
|
60
70
|
for (let animation of context.stashedAnimations) {
|
|
61
71
|
context.activeRange = animation.range;
|
|
62
72
|
$run(function addFragmentAnimation() {
|
package/src/render/hydrate.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Component } from "../types/Component";
|
|
2
2
|
import { type SlotRender } from "../types/SlotRender";
|
|
3
|
+
import $run from "./$run";
|
|
3
4
|
import context from "./context";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -22,4 +23,10 @@ export default function hydrate(
|
|
|
22
23
|
component(parent, null, props, undefined, slots);
|
|
23
24
|
|
|
24
25
|
context.hydrationNode = null;
|
|
26
|
+
|
|
27
|
+
// Now that we've hydrated, we can run $mount effects
|
|
28
|
+
for (let effect of context.mountEffects) {
|
|
29
|
+
$run(effect);
|
|
30
|
+
}
|
|
31
|
+
context.mountEffects.length = 0;
|
|
25
32
|
}
|
package/src/render/nodeNext.ts
CHANGED
|
@@ -2,14 +2,23 @@ import context from "./context";
|
|
|
2
2
|
import { HYDRATION_BRANCH } from "./hydrationMarkers";
|
|
3
3
|
import isComment from "./isComment";
|
|
4
4
|
|
|
5
|
-
// TODO: Should have t_next(node, 3) to get the sibling 3 nodes along
|
|
6
|
-
|
|
7
5
|
/**
|
|
8
6
|
* Gets the next sibling of a node
|
|
9
7
|
*/
|
|
10
|
-
export default function nodeNext(node: Node): Node {
|
|
11
|
-
let nextNode = node.nextSibling;
|
|
8
|
+
export default function nodeNext(node: Node, count?: number): Node {
|
|
9
|
+
let nextNode = checkHydrationNode(node.nextSibling);
|
|
12
10
|
|
|
11
|
+
if (count) {
|
|
12
|
+
for (let i = 1; i < count; i++) {
|
|
13
|
+
nextNode = checkHydrationNode(nextNode!.nextSibling);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// NOTE: We know nextNode is not null as it is being called from generated code
|
|
18
|
+
return nextNode!;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function checkHydrationNode(nextNode: ChildNode | null) {
|
|
13
22
|
if (context.hydrationNode) {
|
|
14
23
|
// Remove hydration comments that are inserted at the start of branches
|
|
15
24
|
// They are just used to split up text nodes that would otherwise be joined in HTML
|
|
@@ -20,7 +29,5 @@ export default function nodeNext(node: Node): Node {
|
|
|
20
29
|
}
|
|
21
30
|
context.hydrationNode = nextNode;
|
|
22
31
|
}
|
|
23
|
-
|
|
24
|
-
// NOTE: We know this is not null as it is being called from generated code
|
|
25
|
-
return nextNode!;
|
|
32
|
+
return nextNode;
|
|
26
33
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Range } from "../types/Range";
|
|
2
2
|
import clearRange from "./clearRange";
|
|
3
|
+
import context from "./context";
|
|
3
4
|
import newRange from "./newRange";
|
|
4
5
|
import popRange from "./popRange";
|
|
5
6
|
import pushRange from "./pushRange";
|
|
@@ -9,7 +10,6 @@ export default function runControlBranch(range: Range, index: number, create: ()
|
|
|
9
10
|
if (index >= 0 && range.index === index) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
|
-
|
|
13
13
|
if (range.children?.length) {
|
|
14
14
|
// Branching ranges have exactly one child
|
|
15
15
|
clearRange(range.children[0]);
|
|
@@ -18,9 +18,19 @@ export default function runControlBranch(range: Range, index: number, create: ()
|
|
|
18
18
|
|
|
19
19
|
const oldRange = pushRange(newRange(), true);
|
|
20
20
|
|
|
21
|
+
// Do NOT re-run the entire control for properties accessed while updating
|
|
22
|
+
// its branches. E.g. we want to re-run the control for `@if ($state.x > 5)`
|
|
23
|
+
// (in runControl) but not for `<span>{$state.text}</span>` (in
|
|
24
|
+
// runControlBranch)
|
|
25
|
+
const oldEffect = context.activeEffect;
|
|
26
|
+
context.activeEffect = null;
|
|
27
|
+
|
|
21
28
|
// Run the create function
|
|
22
29
|
create();
|
|
23
30
|
|
|
31
|
+
// Set the active effect back for the next branch
|
|
32
|
+
context.activeEffect = oldEffect;
|
|
33
|
+
|
|
24
34
|
popRange(oldRange);
|
|
25
35
|
|
|
26
36
|
// Set the index on the branching range
|
package/src/render/runList.ts
CHANGED
|
@@ -23,13 +23,19 @@ export default function runList(
|
|
|
23
23
|
|
|
24
24
|
// Run the list in an effect
|
|
25
25
|
$run(function runList() {
|
|
26
|
-
// Push and pop the control statement on subsequent runs, so that new
|
|
27
|
-
// ranges will be added to its children
|
|
26
|
+
// Push and pop the control statement on subsequent runs, so that new
|
|
27
|
+
// item ranges will be added to its children
|
|
28
28
|
const oldBranchRange = pushRange(range);
|
|
29
29
|
|
|
30
30
|
// Build the array of items with keys and data
|
|
31
31
|
const newItems = buildItems();
|
|
32
32
|
|
|
33
|
+
// Do NOT re-run the list for properties accessed while updating its
|
|
34
|
+
// items. E.g. we want to re-run the list for `@for (item of $items)`
|
|
35
|
+
// (in buildItems, above) but not for `<span>{item.id}</span>` (in
|
|
36
|
+
// runListItems, below)
|
|
37
|
+
context.activeEffect = null;
|
|
38
|
+
|
|
33
39
|
// Run the function that updates the list's items
|
|
34
40
|
runListItems(range, parent, anchor, listItems, newItems, create);
|
|
35
41
|
|
|
@@ -24,6 +24,7 @@ test("attributes -- mounted", async () => {
|
|
|
24
24
|
thing: "thing1",
|
|
25
25
|
dataThing: "thing2",
|
|
26
26
|
description: "a person",
|
|
27
|
+
attr: "val",
|
|
27
28
|
});
|
|
28
29
|
|
|
29
30
|
const container = document.createElement("div");
|
|
@@ -38,6 +39,7 @@ test("attributes -- hydrated", async () => {
|
|
|
38
39
|
thing: "thing1",
|
|
39
40
|
dataThing: "thing2",
|
|
40
41
|
description: "a person",
|
|
42
|
+
attr: "val",
|
|
41
43
|
});
|
|
42
44
|
|
|
43
45
|
const container = document.createElement("div");
|
|
@@ -56,4 +58,5 @@ function check(container: HTMLElement, _: State) {
|
|
|
56
58
|
"caption",
|
|
57
59
|
"this attribute is for a person",
|
|
58
60
|
);
|
|
61
|
+
expect(queryByText(container, "Hello!")).toHaveAttribute("attr", "val");
|
|
59
62
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export default function Attributes() {
|
|
2
2
|
@render {
|
|
3
|
-
<div
|
|
3
|
+
<div
|
|
4
|
+
thing={$props.thing}
|
|
5
|
+
data-thing={$props.dataThing}
|
|
6
|
+
caption="this attribute is for {$props.description}"
|
|
7
|
+
{$props.attr}
|
|
8
|
+
>
|
|
4
9
|
Hello!
|
|
5
10
|
</div>
|
|
6
11
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import $run from "../../../../src/render/$run";
|
|
2
|
+
import $watch from "../../../../src/render/$watch";
|
|
2
3
|
import { type SlotRender } from "../../../../src/types/SlotRender";
|
|
3
4
|
import t_add_fragment from "../../../../src/render/addFragment";
|
|
4
5
|
import t_attribute from "../../../../src/render/setAttribute";
|
|
@@ -15,12 +16,12 @@ export default function Attributes(
|
|
|
15
16
|
// @ts-ignore
|
|
16
17
|
$slots?: Record<string, SlotRender>
|
|
17
18
|
) {
|
|
18
|
-
$props ??= {};
|
|
19
|
+
$props ??= $watch({});
|
|
19
20
|
|
|
20
21
|
/* User interface */
|
|
21
22
|
const t_fragments: DocumentFragment[] = [];
|
|
22
23
|
|
|
23
|
-
const t_fragment_0 = t_fragment($parent.ownerDocument!, t_fragments, 0, `<div data-thing=""> Hello! </div>`);
|
|
24
|
+
const t_fragment_0 = t_fragment($parent.ownerDocument!, t_fragments, 0, `<div data-thing="" {$props.attr}> Hello! </div>`);
|
|
24
25
|
// @ts-ignore
|
|
25
26
|
const t_div_1 = t_root(t_fragment_0) as HTMLDivElement;
|
|
26
27
|
$run(function setAttribute() {
|
|
@@ -32,6 +33,9 @@ export default function Attributes(
|
|
|
32
33
|
$run(function setAttribute() {
|
|
33
34
|
t_attribute(t_div_1, "caption", `this attribute is for ${$props.description}`);
|
|
34
35
|
});
|
|
36
|
+
$run(function setAttribute() {
|
|
37
|
+
t_div_1.setAttribute("attr", $props.attr);
|
|
38
|
+
});
|
|
35
39
|
t_add_fragment(t_fragment_0, $parent, $anchor);
|
|
36
40
|
t_next(t_div_1);
|
|
37
41
|
|
|
@@ -8,10 +8,11 @@ export default function Attributes(
|
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
$slots?: Record<string, ServerSlotRender>
|
|
10
10
|
) {
|
|
11
|
+
$props ??= {};
|
|
11
12
|
|
|
12
13
|
/* User interface */
|
|
13
14
|
let $output = "";
|
|
14
|
-
$output += `<div ${$props.thing ? `thing="${t_attr($props.thing)}"` : ''} ${$props.dataThing ? `data-thing="${t_attr($props.dataThing)}"` : ''} caption="this attribute is for ${t_attr($props.description)}"> Hello! </div>`;
|
|
15
|
+
$output += `<div ${$props.thing ? `thing="${t_attr($props.thing)}"` : ''} ${$props.dataThing ? `data-thing="${t_attr($props.dataThing)}"` : ''} caption="this attribute is for ${t_attr($props.description)}" attr="${t_attr($props.attr)}"> Hello! </div>`;
|
|
15
16
|
|
|
16
17
|
return $output;
|
|
17
18
|
}
|