@torpor/view 0.0.13 → 0.1.0
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 +23 -0
- package/README.md +5 -5
- package/dist/compile.cjs +83 -31
- package/dist/compile.cjs.map +1 -1
- package/dist/compile.js +83 -31
- package/dist/compile.js.map +1 -1
- package/dist/index.cjs +19 -12
- 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 +19 -11
- 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 +14 -8
- package/src/compile/build/client/buildFragment.ts +37 -1
- package/src/compile/build/client/buildFragmentText.ts +5 -0
- package/src/compile/build/client/buildHtmlNode.ts +1 -0
- package/src/compile/build/client/buildSlotNode.ts +4 -1
- package/src/compile/build/server/buildServerCode.ts +5 -0
- package/src/compile/build/server/buildServerComponentNode.ts +4 -1
- package/src/compile/build/server/buildServerElementNode.ts +11 -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/render/$unwrap.ts +1 -1
- package/src/render/addFragment.ts +7 -2
- 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/class.test.ts +6 -1
- package/test/class/components/Class.torp +5 -1
- package/test/class/components/output/Class-client.ts +8 -7
- package/test/class/components/output/Class-server.ts +2 -1
- package/test/class/components/temp/{Class-client-8c3f9e0257cc2b687e9bb7106cccbab94a4b5adf.ts → Class-client-dc885e1e391f38973bd9ea25b7475b07f7c23960.ts} +8 -7
- package/test/class/components/temp/Class-server-d1a2463ba432e10c6f68bd59d1d31949c5a2044f.ts +18 -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 +51 -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/class/components/temp/Class-server-2218c3284845fdab80d1a41ebace9a9e2ddd6fc1.ts +0 -17
- 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.0
|
|
3
|
+
"version": "0.1.0",
|
|
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.21",
|
|
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.1.4"
|
|
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)) {
|
|
@@ -175,8 +178,11 @@ function buildElementAttributes(
|
|
|
175
178
|
// Ignore this special attribute
|
|
176
179
|
} else if (name.startsWith("{") && name.endsWith("}")) {
|
|
177
180
|
// It's a shortcut attribute
|
|
181
|
+
// It could be e.g. {width} or it could be {$state.width}, but
|
|
182
|
+
// in either case we set the value of the width property
|
|
178
183
|
name = name.substring(1, name.length - 1);
|
|
179
|
-
|
|
184
|
+
const propName = name.split(".").at(-1);
|
|
185
|
+
buildRun("setAttribute", `${varName}.setAttribute("${propName}", ${name});`, status, b);
|
|
180
186
|
} else if (value != null && isReactive(value)) {
|
|
181
187
|
// It's a reactive attribute
|
|
182
188
|
if (isFullyReactive(value)) {
|
|
@@ -185,17 +191,17 @@ function buildElementAttributes(
|
|
|
185
191
|
value = `\`${trimQuotes(value).replaceAll("{", "${")}\``;
|
|
186
192
|
}
|
|
187
193
|
|
|
188
|
-
if (name === "
|
|
194
|
+
if (name === "&ref") {
|
|
189
195
|
// Bind the DOM element to a user-defined variable
|
|
190
196
|
b.append(`${value} = ${varName};`);
|
|
191
|
-
} else if (name === "
|
|
197
|
+
} else if (name === "&group") {
|
|
192
198
|
buildBindGroupAttribute(node, varName, value, status, b);
|
|
193
|
-
} else if (name === "
|
|
199
|
+
} else if (name === "&value" || name === "&checked") {
|
|
194
200
|
buildBindAttribute(node, varName, name, value, status, b);
|
|
195
201
|
} 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
|
|
202
|
+
// The :onmount event is faked by us by creating a $mount. This
|
|
203
|
+
// also means that you can have unmount functionality by
|
|
204
|
+
// returning a cleanup function
|
|
199
205
|
buildMount("elMount", `return (${trimEnd(value.trim(), ";")})(${varName});`, status, b);
|
|
200
206
|
} else if (name.startsWith("on")) {
|
|
201
207
|
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) {
|
|
@@ -146,6 +146,7 @@ function buildElementFragmentText(
|
|
|
146
146
|
fragments: Fragment[],
|
|
147
147
|
currentFragment: Fragment,
|
|
148
148
|
) {
|
|
149
|
+
let needsClass = node.scopeStyles;
|
|
149
150
|
currentFragment.text += `<${node.tagName}`;
|
|
150
151
|
let attributesText = node.attributes
|
|
151
152
|
.filter((a) => !a.name.startsWith("on") && !a.name.includes(":"))
|
|
@@ -157,6 +158,7 @@ function buildElementFragmentText(
|
|
|
157
158
|
return `${a.name}=""`;
|
|
158
159
|
}
|
|
159
160
|
} else if (a.name === "class" && node.scopeStyles) {
|
|
161
|
+
needsClass = false;
|
|
160
162
|
let value = a.value
|
|
161
163
|
? `"${trimQuotes(a.value)} torp-${status.styleHash}"`
|
|
162
164
|
: `"torp-${status.styleHash}"`;
|
|
@@ -170,6 +172,9 @@ function buildElementFragmentText(
|
|
|
170
172
|
if (attributesText) {
|
|
171
173
|
currentFragment.text += " " + attributesText;
|
|
172
174
|
}
|
|
175
|
+
if (needsClass) {
|
|
176
|
+
currentFragment.text += ` class="torp-${status.styleHash}"`;
|
|
177
|
+
}
|
|
173
178
|
currentFragment.text += ">";
|
|
174
179
|
for (let child of node.children) {
|
|
175
180
|
buildNodeFragmentText(child, status, fragments, currentFragment);
|
|
@@ -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);
|
|
@@ -73,6 +73,11 @@ function buildServerTemplate(
|
|
|
73
73
|
} else if (script.substring(i, i + "/* @start */".length) === "/* @start */") {
|
|
74
74
|
b.append(script.substring(marker, i));
|
|
75
75
|
|
|
76
|
+
// Make sure we've got $props if we're going to be using it
|
|
77
|
+
if (current.props?.length) {
|
|
78
|
+
b.append(`$props ??= {};`);
|
|
79
|
+
}
|
|
80
|
+
|
|
76
81
|
// Redefine $context so that any newly added properties will only be passed to children
|
|
77
82
|
if (current.contextProps?.length) {
|
|
78
83
|
b.append(`$context = Object.assign({}, $context);`);
|
|
@@ -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);
|
|
@@ -40,6 +40,7 @@ export default function buildServerElementNode(
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
|
|
43
|
+
let needsClass = node.scopeStyles;
|
|
43
44
|
let attributes: string[] = [];
|
|
44
45
|
for (let { name, value } of node.attributes) {
|
|
45
46
|
if (name === "self" && node.tagName === ":element") {
|
|
@@ -62,14 +63,17 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
|
|
|
62
63
|
);
|
|
63
64
|
} else if (name.startsWith("{") && name.endsWith("}")) {
|
|
64
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
|
|
65
68
|
name = name.substring(1, name.length - 1);
|
|
69
|
+
const propName = name.split(".").at(-1);
|
|
66
70
|
status.imports.add("t_attr");
|
|
67
|
-
attributes.push(`${
|
|
71
|
+
attributes.push(`${propName}="\${t_attr(${name})}"`);
|
|
68
72
|
} else if (value != null && isFullyReactive(value)) {
|
|
69
73
|
// It's a reactive attribute
|
|
70
74
|
value = value.substring(1, value.length - 1);
|
|
71
75
|
|
|
72
|
-
if (name === "
|
|
76
|
+
if (name === "&ref" || name === "&value" || name === "&checked" || name === "&group") {
|
|
73
77
|
let defaultValue = "";
|
|
74
78
|
let typeAttribute = node.attributes.find((a) => a.name === "type");
|
|
75
79
|
if (typeAttribute && typeAttribute.value) {
|
|
@@ -96,6 +100,7 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
|
|
|
96
100
|
status.imports.add("t_class");
|
|
97
101
|
if (node.scopeStyles) {
|
|
98
102
|
value += `, "torp-${status.styleHash}"`;
|
|
103
|
+
needsClass = false;
|
|
99
104
|
}
|
|
100
105
|
attributes.push(`class="\${t_class(${value})}"`);
|
|
101
106
|
} else if (name === ":style") {
|
|
@@ -118,6 +123,7 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
|
|
|
118
123
|
? `"${trimQuotes(value)} torp-${status.styleHash}"`
|
|
119
124
|
: `"torp-${status.styleHash}"`;
|
|
120
125
|
attributes.push(`${name}="${trimQuotes(value).replaceAll('"', """)}"`);
|
|
126
|
+
needsClass = false;
|
|
121
127
|
} else if (value != null) {
|
|
122
128
|
// Just set the attribute
|
|
123
129
|
// TODO: Probably check if it's a boolean attribute e.g. disabled
|
|
@@ -126,5 +132,8 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
|
|
|
126
132
|
attributes.push(`${name}`);
|
|
127
133
|
}
|
|
128
134
|
}
|
|
135
|
+
if (needsClass) {
|
|
136
|
+
attributes.push(`class="torp-${status.styleHash}"`);
|
|
137
|
+
}
|
|
129
138
|
return attributes.join(" ");
|
|
130
139
|
}
|
|
@@ -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/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,17 @@ 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
|
+
// functions, add our stashed events and play our stashed animations
|
|
45
45
|
if (!parentIsFragment) {
|
|
46
46
|
// Set the active range for each event and animation so it will get
|
|
47
47
|
// attached to the right one and set it back afterwards
|
|
48
48
|
|
|
49
|
+
for (let effect of context.mountEffects) {
|
|
50
|
+
$run(effect);
|
|
51
|
+
}
|
|
52
|
+
context.mountEffects.length = 0;
|
|
53
|
+
|
|
49
54
|
for (let event of context.stashedEvents) {
|
|
50
55
|
context.activeRange = event.range;
|
|
51
56
|
$run(function addFragmentEvent() {
|
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
|
}
|