diff --git a/.changeset/wicked-eagles-hide.md b/.changeset/wicked-eagles-hide.md
new file mode 100644
index 00000000..a958e067
--- /dev/null
+++ b/.changeset/wicked-eagles-hide.md
@@ -0,0 +1,11 @@
+---
+"@triplex/ws-client": patch
+"@triplex/bridge": patch
+"@triplex/client": patch
+"@triplex/editor": patch
+"@triplex/server": patch
+"@triplex/scene": patch
+"@triplex/run": patch
+---
+
+Packages have been moved into namedspaced folders.
diff --git a/package.json b/package.json
index 447fed39..9c5257ea 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,9 @@
"workspaces": [
"apps/docs",
"examples/*",
- "packages/*"
+ "packages/*",
+ "packages/*/*",
+ "!packages/create-triplex-project/*"
],
"scripts": {
"build": "yarn clean && yarn workspaces run build",
diff --git a/packages/bridge/.swcrc b/packages/bridge/.swcrc
deleted file mode 100644
index 2add8c2b..00000000
--- a/packages/bridge/.swcrc
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/swcrc",
- "minify": true,
- "sourceMaps": false,
- "jsc": {
- "minify": {
- "compress": true,
- "mangle": true
- },
- "target": "es2017",
- "parser": {
- "syntax": "typescript"
- }
- }
-}
diff --git a/packages/bridge/CHANGELOG.md b/packages/bridge/CHANGELOG.md
deleted file mode 100644
index 1226c080..00000000
--- a/packages/bridge/CHANGELOG.md
+++ /dev/null
@@ -1,272 +0,0 @@
-# @triplex/bridge
-
-## 0.58.2
-
-### Patch Changes
-
-- b5247c2: Apply lint and prettier fixes.
-
-## 0.58.1
-
-## 0.58.0
-
-### Minor Changes
-
-- 3e1e081: Separate soft refresh from hard refresh.
-
-## 0.57.2
-
-## 0.57.1
-
-## 0.57.0
-
-### Minor Changes
-
-- 5c1fc3d: Add editing child jsx elements through the Triplex UI.
-- 2b61384: Adding an asset is now contextual, the original button adds to the
- open component, while the add buttons on each element in the left scene panel
- add to it as a child.
-
-## 0.56.1
-
-## 0.56.0
-
-### Minor Changes
-
-- 32a110f: Add top-level scene component to the scene panel. When selected users
- can modify the props during their seession to see what happens.
-
-### Patch Changes
-
-- 2e53a2e: Turn off type declaration maps.
-
-## 0.55.3
-
-## 0.55.2
-
-## 0.55.1
-
-### Patch Changes
-
-- ea86fdc: Add license banner.
-
-## 0.55.0
-
-## 0.54.2
-
-## 0.54.1
-
-## 0.54.0
-
-### Minor Changes
-
-- 8fad65a: Adds camera type to controls menu, allowing you to switch between
- perspective and orthographic camera.
-- e0038f6: Add support for viewing through a user land camera.
-
-## 0.53.1
-
-## 0.53.0
-
-### Minor Changes
-
-- c71412b: Adds refresh scene action available in the File menubar and through
- cmd/ctrl + r.
-
-## 0.52.0
-
-### Minor Changes
-
-- 8d532f5: Editor now shows build time and runtime errors in an error overlay.
-
-## 0.51.1
-
-## 0.51.0
-
-## 0.50.1
-
-## 0.50.0
-
-### Minor Changes
-
-- 8ea575b: Built output is now mangled.
-
-## 0.49.0
-
-## 0.48.0
-
-## 0.47.0
-
-## 0.46.4
-
-## 0.46.3
-
-## 0.46.2
-
-## 0.46.1
-
-## 0.46.0
-
-## 0.45.1
-
-## 0.45.0
-
-## 0.44.0
-
-### Minor Changes
-
-- 0242833: Scene now removes intermediate state when resetting.
-- 4d8d9cc: Builds are now minified.
-- 557648e: Editor has been extracted out of the client dev server and now is
- bundled when published to npm.
-
-## 0.43.0
-
-### Minor Changes
-
-- b7bbeba: When adding a new element to the scene if you have a selection it
- will be added as a child. If you have no selection it will be added to the
- root component.
-
-## 0.42.0
-
-## 0.41.0
-
-## 0.40.0
-
-## 0.39.0
-
-## 0.38.0
-
-## 0.37.0
-
-### Minor Changes
-
-- 23fe64a: Adds delete scene object. Access through the context panel when
- focusing on a scene object.
-- 1a2ecea: Iframe client bridge can now wait for a response from host.
-
-## 0.36.0
-
-## 0.35.0
-
-## 0.34.0
-
-### Minor Changes
-
-- 2a64658: The context panel now displays all available props on a component
- even if they aren't yet declared thanks to the TypeScript compiler and
- ts-morph. Not all prop types are supported currently, if you have one that you
- expected to be available but isn't please reach out.
-
-## 0.33.0
-
-### Minor Changes
-
-- 1067d23: Adds transform controls to the ui.
-
-## 0.32.0
-
-### Minor Changes
-
-- c87a5f3: Undo/redo now available. When manipulating the scene through
- transform controls or the context panel each persisted manipulation will be
- able to be undone (and redone) using hotkeys and the edit menu actions.
-
-## 0.31.0
-
-## 0.30.0
-
-### Minor Changes
-
-- 0bb6119: Adds support for updating scene objects through the context panel.
-
-## 0.29.0
-
-## 0.28.0
-
-## 0.27.0
-
-## 0.26.0
-
-## 0.25.0
-
-## 0.24.0
-
-## 0.23.0
-
-## 0.22.0
-
-## 0.21.0
-
-## 0.20.0
-
-### Minor Changes
-
-- 1c9771d: Focus events now only use line and column numbers.
-
-## 0.19.0
-
-## 0.18.0
-
-## 0.17.0
-
-## 0.16.0
-
-### Minor Changes
-
-- d8e1602: Fixed non-scene objects not being able to be selected through the UI.
-- 7ff35f3: Upgrades @react-three/fiber to latest.
-- 2fa7c45: Adds author field to package.json.
-
-## 0.15.0
-
-### Minor Changes
-
-- e54e0f8: Bridge events now flow unidirectionally enabling the editor ui to
- initiate events to the scene, such as navigate and focus.
-
-## 0.14.0
-
-## 0.7.0
-
-### Minor Changes
-
-- a4d6882: Passes name during object focus.
-
-## 0.6.0
-
-### Minor Changes
-
-- 3c725bc: Force release all packages.
-
-## 0.5.0
-
-### Minor Changes
-
-- ac9624f: Fixes client/host race condition where host would send events before
- the client has connected.
-
-## 0.4.0
-
-### Minor Changes
-
-- b144bb1: Package `build` now use `swc` and `tsc` directly.
-
-## 0.3.0
-
-### Minor Changes
-
-- bbc457e: Fixes some bugs preventing triplex from being able to be ran via cli.
-
-## 0.2.0
-
-### Minor Changes
-
-- 08a03af: Fixes publish to build before pushing.
-
-## 0.1.0
-
-### Minor Changes
-
-- 9c120b4: Initial release.
diff --git a/packages/bridge/LICENSE b/packages/bridge/LICENSE
deleted file mode 100644
index 741b8fab..00000000
--- a/packages/bridge/LICENSE
+++ /dev/null
@@ -1,632 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
-Copyright (C) 2007 Free Software Foundation, Inc. Everyone is
-permitted to copy and distribute verbatim copies of this license document, but
-changing it is not allowed.
-
- Preamble
-
-The GNU General Public License is a free, copyleft license for software and
-other kinds of works.
-
-The licenses for most software and other practical works are designed to take
-away your freedom to share and change the works. By contrast, the GNU General
-Public License is intended to guarantee your freedom to share and change all
-versions of a program--to make sure it remains free software for all its users.
-We, the Free Software Foundation, use the GNU General Public License for most of
-our software; it applies also to any other work released this way by its
-authors. You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom to
-distribute copies of free software (and charge for them if you wish), that you
-receive source code or can get it if you want it, that you can change the
-software or use pieces of it in new free programs, and that you know you can do
-these things.
-
-To protect your rights, we need to prevent others from denying you these rights
-or asking you to surrender the rights. Therefore, you have certain
-responsibilities if you distribute copies of the software, or if you modify it:
-responsibilities to respect the freedom of others.
-
-For example, if you distribute copies of such a program, whether gratis or for a
-fee, you must pass on to the recipients the same freedoms that you received. You
-must make sure that they, too, receive or can get the source code. And you must
-show them these terms so they know their rights.
-
-Developers that use the GNU GPL protect your rights with two steps: (1) assert
-copyright on the software, and (2) offer you this License giving you legal
-permission to copy, distribute and/or modify it.
-
-For the developers' and authors' protection, the GPL clearly explains that there
-is no warranty for this free software. For both users' and authors' sake, the
-GPL requires that modified versions be marked as changed, so that their problems
-will not be attributed erroneously to authors of previous versions.
-
-Some devices are designed to deny users access to install or run modified
-versions of the software inside them, although the manufacturer can do so. This
-is fundamentally incompatible with the aim of protecting users' freedom to
-change the software. The systematic pattern of such abuse occurs in the area of
-products for individuals to use, which is precisely where it is most
-unacceptable. Therefore, we have designed this version of the GPL to prohibit
-the practice for those products. If such problems arise substantially in other
-domains, we stand ready to extend this provision to those domains in future
-versions of the GPL, as needed to protect the freedom of users.
-
-Finally, every program is threatened constantly by software patents. States
-should not allow patents to restrict development and use of software on
-general-purpose computers, but in those that do, we wish to avoid the special
-danger that patents applied to a free program could make it effectively
-proprietary. To prevent this, the GPL assures that patents cannot be used to
-render the program non-free.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
- TERMS AND CONDITIONS
-
-0. Definitions.
-
-"This License" refers to version 3 of the GNU General Public License.
-
-"Copyright" also means copyright-like laws that apply to other kinds of works,
-such as semiconductor masks.
-
-"The Program" refers to any copyrightable work licensed under this License. Each
-licensee is addressed as "you". "Licensees" and "recipients" may be individuals
-or organizations.
-
-To "modify" a work means to copy from or adapt all or part of the work in a
-fashion requiring copyright permission, other than the making of an exact copy.
-The resulting work is called a "modified version" of the earlier work or a work
-"based on" the earlier work.
-
-A "covered work" means either the unmodified Program or a work based on the
-Program.
-
-To "propagate" a work means to do anything with it that, without permission,
-would make you directly or secondarily liable for infringement under applicable
-copyright law, except executing it on a computer or modifying a private copy.
-Propagation includes copying, distribution (with or without modification),
-making available to the public, and in some countries other activities as well.
-
-To "convey" a work means any kind of propagation that enables other parties to
-make or receive copies. Mere interaction with a user through a computer network,
-with no transfer of a copy, is not conveying.
-
-An interactive user interface displays "Appropriate Legal Notices" to the extent
-that it includes a convenient and prominently visible feature that (1) displays
-an appropriate copyright notice, and (2) tells the user that there is no
-warranty for the work (except to the extent that warranties are provided), that
-licensees may convey the work under this License, and how to view a copy of this
-License. If the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-1. Source Code.
-
-The "source code" for a work means the preferred form of the work for making
-modifications to it. "Object code" means any non-source form of a work.
-
-A "Standard Interface" means an interface that either is an official standard
-defined by a recognized standards body, or, in the case of interfaces specified
-for a particular programming language, one that is widely used among developers
-working in that language.
-
-The "System Libraries" of an executable work include anything, other than the
-work as a whole, that (a) is included in the normal form of packaging a Major
-Component, but which is not part of that Major Component, and (b) serves only to
-enable use of the work with that Major Component, or to implement a Standard
-Interface for which an implementation is available to the public in source code
-form. A "Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system (if any) on
-which the executable work runs, or a compiler used to produce the work, or an
-object code interpreter used to run it.
-
-The "Corresponding Source" for a work in object code form means all the source
-code needed to generate, install, and (for an executable work) run the object
-code and to modify the work, including scripts to control those activities.
-However, it does not include the work's System Libraries, or general-purpose
-tools or generally available free programs which are used unmodified in
-performing those activities but which are not part of the work. For example,
-Corresponding Source includes interface definition files associated with source
-files for the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require, such as by
-intimate data communication or control flow between those subprograms and other
-parts of the work.
-
-The Corresponding Source need not include anything that users can regenerate
-automatically from other parts of the Corresponding Source.
-
-The Corresponding Source for a work in source code form is that same work.
-
-2. Basic Permissions.
-
-All rights granted under this License are granted for the term of copyright on
-the Program, and are irrevocable provided the stated conditions are met. This
-License explicitly affirms your unlimited permission to run the unmodified
-Program. The output from running a covered work is covered by this License only
-if the output, given its content, constitutes a covered work. This License
-acknowledges your rights of fair use or other equivalent, as provided by
-copyright law.
-
-You may make, run and propagate covered works that you do not convey, without
-conditions so long as your license otherwise remains in force. You may convey
-covered works to others for the sole purpose of having them make modifications
-exclusively for you, or provide you with facilities for running those works,
-provided that you comply with the terms of this License in conveying all
-material for which you do not control copyright. Those thus making or running
-the covered works for you must do so exclusively on your behalf, under your
-direction and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-Conveying under any other circumstances is permitted solely under the conditions
-stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
-
-3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-No covered work shall be deemed part of an effective technological measure under
-any applicable law fulfilling obligations under article 11 of the WIPO copyright
-treaty adopted on 20 December 1996, or similar laws prohibiting or restricting
-circumvention of such measures.
-
-When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention is
-effected by exercising rights under this License with respect to the covered
-work, and you disclaim any intention to limit operation or modification of the
-work as a means of enforcing, against the work's users, your or third parties'
-legal rights to forbid circumvention of technological measures.
-
-4. Conveying Verbatim Copies.
-
-You may convey verbatim copies of the Program's source code as you receive it,
-in any medium, provided that you conspicuously and appropriately publish on each
-copy an appropriate copyright notice; keep intact all notices stating that this
-License and any non-permissive terms added in accord with section 7 apply to the
-code; keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-You may charge any price or no price for each copy that you convey, and you may
-offer support or warranty protection for a fee.
-
-5. Conveying Modified Source Versions.
-
-You may convey a work based on the Program, or the modifications to produce it
-from the Program, in the form of source code under the terms of section 4,
-provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
-A compilation of a covered work with other separate and independent works, which
-are not by their nature extensions of the covered work, and which are not
-combined with it such as to form a larger program, in or on a volume of a
-storage or distribution medium, is called an "aggregate" if the compilation and
-its resulting copyright are not used to limit the access or legal rights of the
-compilation's users beyond what the individual works permit. Inclusion of a
-covered work in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-6. Conveying Non-Source Forms.
-
-You may convey a covered work in object code form under the terms of sections 4
-and 5, provided that you also convey the machine-readable Corresponding Source
-under the terms of this License, in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
-A separable portion of the object code, whose source code is excluded from the
-Corresponding Source as a System Library, need not be included in conveying the
-object code work.
-
-A "User Product" is either (1) a "consumer product", which means any tangible
-personal property which is normally used for personal, family, or household
-purposes, or (2) anything designed or sold for incorporation into a dwelling. In
-determining whether a product is a consumer product, doubtful cases shall be
-resolved in favor of coverage. For a particular product received by a particular
-user, "normally used" refers to a typical or common use of that class of
-product, regardless of the status of the particular user or of the way in which
-the particular user actually uses, or expects or is expected to use, the
-product. A product is a consumer product regardless of whether the product has
-substantial commercial, industrial or non-consumer uses, unless such uses
-represent the only significant mode of use of the product.
-
-"Installation Information" for a User Product means any methods, procedures,
-authorization keys, or other information required to install and execute
-modified versions of a covered work in that User Product from a modified version
-of its Corresponding Source. The information must suffice to ensure that the
-continued functioning of the modified object code is in no case prevented or
-interfered with solely because modification has been made.
-
-If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as part of a
-transaction in which the right of possession and use of the User Product is
-transferred to the recipient in perpetuity or for a fixed term (regardless of
-how the transaction is characterized), the Corresponding Source conveyed under
-this section must be accompanied by the Installation Information. But this
-requirement does not apply if neither you nor any third party retains the
-ability to install modified object code on the User Product (for example, the
-work has been installed in ROM).
-
-The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates for a
-work that has been modified or installed by the recipient, or for the User
-Product in which it has been modified or installed. Access to a network may be
-denied when the modification itself materially and adversely affects the
-operation of the network or violates the rules and protocols for communication
-across the network.
-
-Corresponding Source conveyed, and Installation Information provided, in accord
-with this section must be in a format that is publicly documented (and with an
-implementation available to the public in source code form), and must require no
-special password or key for unpacking, reading or copying.
-
-7. Additional Terms.
-
-"Additional permissions" are terms that supplement the terms of this License by
-making exceptions from one or more of its conditions. Additional permissions
-that are applicable to the entire Program shall be treated as though they were
-included in this License, to the extent that they are valid under applicable
-law. If additional permissions apply only to part of the Program, that part may
-be used separately under those permissions, but the entire Program remains
-governed by this License without regard to the additional permissions.
-
-When you convey a copy of a covered work, you may at your option remove any
-additional permissions from that copy, or from any part of it. (Additional
-permissions may be written to require their own removal in certain cases when
-you modify the work.) You may place additional permissions on material, added by
-you to a covered work, for which you have or can give appropriate copyright
-permission.
-
-Notwithstanding any other provision of this License, for material you add to a
-covered work, you may (if authorized by the copyright holders of that material)
-supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
-All other non-permissive additional terms are considered "further restrictions"
-within the meaning of section 10. If the Program as you received it, or any part
-of it, contains a notice stating that it is governed by this License along with
-a term that is a further restriction, you may remove that term. If a license
-document contains a further restriction but permits relicensing or conveying
-under this License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does not survive
-such relicensing or conveying.
-
-If you add terms to a covered work in accord with this section, you must place,
-in the relevant source files, a statement of the additional terms that apply to
-those files, or a notice indicating where to find the applicable terms.
-
-Additional terms, permissive or non-permissive, may be stated in the form of a
-separately written license, or stated as exceptions; the above requirements
-apply either way.
-
-8. Termination.
-
-You may not propagate or modify a covered work except as expressly provided
-under this License. Any attempt otherwise to propagate or modify it is void, and
-will automatically terminate your rights under this License (including any
-patent licenses granted under the third paragraph of section 11).
-
-However, if you cease all violation of this License, then your license from a
-particular copyright holder is reinstated (a) provisionally, unless and until
-the copyright holder explicitly and finally terminates your license, and (b)
-permanently, if the copyright holder fails to notify you of the violation by
-some reasonable means prior to 60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is reinstated
-permanently if the copyright holder notifies you of the violation by some
-reasonable means, this is the first time you have received notice of violation
-of this License (for any work) from that copyright holder, and you cure the
-violation prior to 30 days after your receipt of the notice.
-
-Termination of your rights under this section does not terminate the licenses of
-parties who have received copies or rights from you under this License. If your
-rights have been terminated and not permanently reinstated, you do not qualify
-to receive new licenses for the same material under section 10.
-
-9. Acceptance Not Required for Having Copies.
-
-You are not required to accept this License in order to receive or run a copy of
-the Program. Ancillary propagation of a covered work occurring solely as a
-consequence of using peer-to-peer transmission to receive a copy likewise does
-not require acceptance. However, nothing other than this License grants you
-permission to propagate or modify any covered work. These actions infringe
-copyright if you do not accept this License. Therefore, by modifying or
-propagating a covered work, you indicate your acceptance of this License to do
-so.
-
-10. Automatic Licensing of Downstream Recipients.
-
-Each time you convey a covered work, the recipient automatically receives a
-license from the original licensors, to run, modify and propagate that work,
-subject to this License. You are not responsible for enforcing compliance by
-third parties with this License.
-
-An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered work results
-from an entity transaction, each party to that transaction who receives a copy
-of the work also receives whatever licenses to the work the party's predecessor
-in interest had or could give under the previous paragraph, plus a right to
-possession of the Corresponding Source of the work from the predecessor in
-interest, if the predecessor has it or can get it with reasonable efforts.
-
-You may not impose any further restrictions on the exercise of the rights
-granted or affirmed under this License. For example, you may not impose a
-license fee, royalty, or other charge for exercise of rights granted under this
-License, and you may not initiate litigation (including a cross-claim or
-counterclaim in a lawsuit) alleging that any patent claim is infringed by
-making, using, selling, offering for sale, or importing the Program or any
-portion of it.
-
-11. Patents.
-
-A "contributor" is a copyright holder who authorizes use under this License of
-the Program or a work on which the Program is based. The work thus licensed is
-called the contributor's "contributor version".
-
-A contributor's "essential patent claims" are all patent claims owned or
-controlled by the contributor, whether already acquired or hereafter acquired,
-that would be infringed by some manner, permitted by this License, of making,
-using, or selling its contributor version, but do not include claims that would
-be infringed only as a consequence of further modification of the contributor
-version. For purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of this License.
-
-Each contributor grants you a non-exclusive, worldwide, royalty-free patent
-license under the contributor's essential patent claims, to make, use, sell,
-offer for sale, import and otherwise run, modify and propagate the contents of
-its contributor version.
-
-In the following three paragraphs, a "patent license" is any express agreement
-or commitment, however denominated, not to enforce a patent (such as an express
-permission to practice a patent or covenant not to sue for patent infringement).
-To "grant" such a patent license to a party means to make such an agreement or
-commitment not to enforce a patent against the party.
-
-If you convey a covered work, knowingly relying on a patent license, and the
-Corresponding Source of the work is not available for anyone to copy, free of
-charge and under the terms of this License, through a publicly available network
-server or other readily accessible means, then you must either (1) cause the
-Corresponding Source to be so available, or (2) arrange to deprive yourself of
-the benefit of the patent license for this particular work, or (3) arrange, in a
-manner consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have actual
-knowledge that, but for the patent license, your conveying the covered work in a
-country, or your recipient's use of the covered work in a country, would
-infringe one or more identifiable patents in that country that you have reason
-to believe are valid.
-
-If, pursuant to or in connection with a single transaction or arrangement, you
-convey, or propagate by procuring conveyance of, a covered work, and grant a
-patent license to some of the parties receiving the covered work authorizing
-them to use, propagate, modify or convey a specific copy of the covered work,
-then the patent license you grant is automatically extended to all recipients of
-the covered work and works based on it.
-
-A patent license is "discriminatory" if it does not include within the scope of
-its coverage, prohibits the exercise of, or is conditioned on the non-exercise
-of one or more of the rights that are specifically granted under this License.
-You may not convey a covered work if you are a party to an arrangement with a
-third party that is in the business of distributing software, under which you
-make payment to the third party based on the extent of your activity of
-conveying the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory patent
-license (a) in connection with copies of the covered work conveyed by you (or
-copies made from those copies), or (b) primarily for and in connection with
-specific products or compilations that contain the covered work, unless you
-entered into that arrangement, or that patent license was granted, prior to 28
-March 2007.
-
-Nothing in this License shall be construed as excluding or limiting any implied
-license or other defenses to infringement that may otherwise be available to you
-under applicable patent law.
-
-12. No Surrender of Others' Freedom.
-
-If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not excuse
-you from the conditions of this License. If you cannot convey a covered work so
-as to satisfy simultaneously your obligations under this License and any other
-pertinent obligations, then as a consequence you may not convey it at all. For
-example, if you agree to terms that obligate you to collect a royalty for
-further conveying from those to whom you convey the Program, the only way you
-could satisfy both those terms and this License would be to refrain entirely
-from conveying the Program.
-
-13. Use with the GNU Affero General Public License.
-
-Notwithstanding any other provision of this License, you have permission to link
-or combine any covered work with a work licensed under version 3 of the GNU
-Affero General Public License into a single combined work, and to convey the
-resulting work. The terms of this License will continue to apply to the part
-which is the covered work, but the special requirements of the GNU Affero
-General Public License, section 13, concerning interaction through a network
-will apply to the combination as such.
-
-14. Revised Versions of this License.
-
-The Free Software Foundation may publish revised and/or new versions of the GNU
-General Public License from time to time. Such new versions will be similar in
-spirit to the present version, but may differ in detail to address new problems
-or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies
-that a certain numbered version of the GNU General Public License "or any later
-version" applies to it, you have the option of following the terms and
-conditions either of that numbered version or of any later version published by
-the Free Software Foundation. If the Program does not specify a version number
-of the GNU General Public License, you may choose any version ever published by
-the Free Software Foundation.
-
-If the Program specifies that a proxy can decide which future versions of the
-GNU General Public License can be used, that proxy's public statement of
-acceptance of a version permanently authorizes you to choose that version for
-the Program.
-
-Later license versions may give you additional or different permissions.
-However, no additional obligations are imposed on any author or copyright holder
-as a result of your choosing to follow a later version.
-
-15. Disclaimer of Warranty.
-
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
-PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
-QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
-DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-16. Limitation of Liability.
-
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
-COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
-PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
-THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
-INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
-HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-17. Interpretation of Sections 15 and 16.
-
-If the disclaimer of warranty and limitation of liability provided above cannot
-be given local legal effect according to their terms, reviewing courts shall
-apply local law that most closely approximates an absolute waiver of all civil
-liability in connection with the Program, unless a warranty or assumption of
-liability accompanies a copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest possible use
-to the public, the best way to achieve this is to make it free software which
-everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to attach
-them to the start of each source file to most effectively state the exclusion of
-warranty; and each file should have at least the "copyright" line and a pointer
-to where the full notice is found.
-
- Triplex — The React Three Fiber editor
- Copyright (C) 2022-Present Michael Dougall
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program does terminal interaction, make it output a short notice like
-this when it starts in an interactive mode:
-
- Triplex Copyright (C) 2022-Present Michael Dougall
- This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands might be
-different; for a GUI interface, you would use an "about box".
-
-You should also get your employer (if you work as a programmer) or school, if
-any, to sign a "copyright disclaimer" for the program, if necessary. For more
-information on this, and how to apply and follow the GNU GPL, see
-.
-
-The GNU General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may consider
-it more useful to permit linking proprietary applications with the library. If
-this is what you want to do, use the GNU Lesser General Public License instead
-of this License. But first, please read
-.
diff --git a/packages/bridge/README.md b/packages/bridge/README.md
deleted file mode 100644
index 0cd5d93c..00000000
--- a/packages/bridge/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# @triplex/bridge
diff --git a/packages/bridge/package.json b/packages/bridge/package.json
deleted file mode 100644
index 4a44284f..00000000
--- a/packages/bridge/package.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "name": "@triplex/bridge",
- "version": "0.58.2",
- "private": true,
- "description": "The React Three Fiber editor.",
- "license": "GPL-3.0",
- "author": "Michael Dougall (https://twitter.com/itsdouges)",
- "exports": {
- "./host": {
- "module": "./src/host.ts",
- "types": "./src/host.ts"
- },
- "./client": {
- "module": "./src/client.ts",
- "types": "./src/client.ts"
- }
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "swc ./src -d ./dist",
- "typedef": "tsc"
- },
- "devDependencies": {
- "@swc/cli": "^0.1.59",
- "@swc/core": "^1.3.28",
- "typescript": "^4.9.4"
- },
- "publishConfig": {
- "exports": {
- "./host": {
- "module": "./dist/host.js",
- "types": "./dist/host.d.ts"
- },
- "./client": {
- "module": "./dist/client.js",
- "types": "./dist/client.d.ts"
- }
- },
- "types": "./dist/index.d.ts"
- }
-}
diff --git a/packages/bridge/src/client.ts b/packages/bridge/src/client.ts
deleted file mode 100644
index 431951e1..00000000
--- a/packages/bridge/src/client.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import type {
- ClientSendEventData,
- ClientSendEventName,
- ClientSendEventResponse,
- HostSendEventData,
- HostSendEventName,
- HostSendEventResponse,
-} from "./types";
-
-export function listen(
- eventName: TEvent,
- callback: (
- data: HostSendEventData[TEvent]
- ) =>
- | void
- | HostSendEventResponse[TEvent]
- | Promise
-) {
- const cb = async (e: MessageEvent) => {
- if (typeof e.data === "object" && e.data.eventName === eventName) {
- const value = await callback(e.data.data);
-
- if (value !== undefined) {
- respond(eventName, value);
- } else if (process.env.NODE_ENV === "test") {
- // Always respond in a test environment so we can assert that the event was called
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- respond(eventName, undefined as any);
- }
- }
- };
-
- window.addEventListener("message", cb, false);
-
- return () => {
- window.removeEventListener("message", cb, false);
- };
-}
-
-export function send(
- eventName: TEvent,
- data: ClientSendEventData[TEvent],
- awaitResponse = false
-): Promise {
- window.top?.postMessage({ data, eventName }, "*");
-
- if (awaitResponse) {
- return new Promise((resolve) => {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const responseName = `${eventName}Response` as any;
- const cleanup = listen(responseName, (responseValue) => {
- resolve(responseValue as ClientSendEventResponse[TEvent]);
- cleanup();
- });
- });
- }
-
- return Promise.resolve(undefined as ClientSendEventResponse[TEvent]);
-}
-
-function respond(
- eventName: TEvent,
- data: HostSendEventResponse[TEvent]
-) {
- window.top?.postMessage({ data, eventName: `${eventName}Response` }, "*");
-}
-
-export { compose } from "./compose";
diff --git a/packages/bridge/src/compose.ts b/packages/bridge/src/compose.ts
deleted file mode 100644
index b680d89d..00000000
--- a/packages/bridge/src/compose.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-export function compose(args: (() => void)[]) {
- return () => {
- args.forEach((arg) => arg());
- };
-}
diff --git a/packages/bridge/src/host.ts b/packages/bridge/src/host.ts
deleted file mode 100644
index b2cc915b..00000000
--- a/packages/bridge/src/host.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import type {
- ClientSendEventData,
- ClientSendEventName,
- ClientSendEventResponse,
- HostSendEventData,
- HostSendEventName,
- HostSendEventResponse,
-} from "./types";
-
-export function listen(
- eventName: TEvent,
- callback: (
- data: ClientSendEventData[TEvent]
- ) =>
- | void
- | ClientSendEventResponse[TEvent]
- | Promise
-) {
- const cb = async (e: MessageEvent) => {
- if (typeof e.data === "object" && e.data.eventName === eventName) {
- const value = await callback(e.data.data);
-
- if (value !== undefined) {
- respond(eventName, value);
- }
- }
- };
-
- window.addEventListener("message", cb, false);
-
- return () => {
- window.removeEventListener("message", cb, false);
- };
-}
-
-function getMessageWindow() {
- const iframe = document.getElementsByTagName("iframe")[0];
- const messageWindow =
- process.env.NODE_ENV === "test"
- ? // In a test environment there won't be an iframe so we just return the window
- window
- : iframe.contentWindow;
-
- return messageWindow;
-}
-
-export function send(
- eventName: TEvent,
- data: HostSendEventData[TEvent],
- awaitResponse = false
-): Promise {
- const messageWindow = getMessageWindow();
-
- messageWindow?.postMessage(
- {
- data,
- eventName,
- },
- "*"
- );
-
- if (awaitResponse) {
- return new Promise((resolve) => {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const responseName = `${eventName}Response` as any;
- const cleanup = listen(responseName, (responseValue) => {
- resolve(responseValue as HostSendEventResponse[TEvent]);
- cleanup();
- });
- });
- }
-
- return Promise.resolve(undefined as HostSendEventResponse[TEvent]);
-}
-
-function respond(
- eventName: TEvent,
- data: ClientSendEventResponse[TEvent]
-) {
- const messageWindow = getMessageWindow();
-
- messageWindow?.postMessage(
- {
- data,
- eventName: `${eventName}Response`,
- },
- "*"
- );
-}
-
-export { compose } from "./compose";
diff --git a/packages/bridge/src/types.ts b/packages/bridge/src/types.ts
deleted file mode 100644
index 4879b333..00000000
--- a/packages/bridge/src/types.ts
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-export type ClientSendEventName = keyof ClientSendEventData;
-
-export interface ClientSendEventData {
- "trplx:onAddNewComponent": {
- target?: {
- action: "child";
- column: number;
- exportName: string;
- line: number;
- path: string;
- };
- type:
- | {
- exportName: string;
- name: string;
- path: string;
- props: Record;
- type: "custom";
- }
- | {
- name: string;
- props: Record;
- type: "host";
- };
- };
- "trplx:onCameraTypeChange": {
- type: "perspective" | "orthographic";
- };
- "trplx:onConfirmSceneObjectProp": {
- column: number;
- line: number;
- path: string;
- propName: string;
- propValue: unknown;
- };
- "trplx:onConnected": undefined;
- "trplx:onError": {
- col: number;
- line: number;
- message: string;
- source: string;
- stack: string;
- };
- "trplx:onOpenFileHmr": undefined;
- "trplx:onSceneObjectBlur": undefined;
- "trplx:onSceneObjectFocus": {
- column: number;
- line: number;
- parentPath: string;
- path: string;
- };
- "trplx:onSceneObjectNavigated": {
- encodedProps: string;
- entered?: boolean;
- exportName: string;
- path: string;
- };
- "trplx:onStateChange": {
- change: "userCamera";
- data: { column: number; line: number; path: string };
- };
- "trplx:onTransformChange": {
- mode: "translate" | "scale" | "rotate";
- };
- "trplx:requestDeleteSceneObject": undefined;
- "trplx:requestRedo": undefined;
- "trplx:requestSave": undefined;
- "trplx:requestUndo": undefined;
-}
-
-export interface ClientSendEventResponse {
- "trplx:onAddNewComponent": {
- column: number;
- line: number;
- path: string;
- };
- "trplx:onCameraTypeChange": void;
- "trplx:onConfirmSceneObjectProp": void;
- "trplx:onConnected": void;
- "trplx:onError": void;
- "trplx:onOpenFileHmr": void;
- "trplx:onSceneObjectBlur": void;
- "trplx:onSceneObjectFocus": void;
- "trplx:onSceneObjectNavigated": void;
- "trplx:onStateChange": void;
- "trplx:onTransformChange": void;
- "trplx:requestDeleteSceneObject": void;
- "trplx:requestRedo": void;
- "trplx:requestSave": void;
- "trplx:requestUndo": void;
-}
-
-export type HostSendEventName = keyof HostSendEventData;
-
-export interface HostSendEventData {
- "trplx:requestAction": { action: "viewFocusedCamera" | "resetCamera" };
- "trplx:requestAddNewComponent": {
- target?: {
- action: "child";
- column: number;
- exportName: string;
- line: number;
- path: string;
- };
- type:
- | {
- exportName: string;
- name: string;
- path: string;
- props: Record;
- type: "custom";
- }
- | {
- name: string;
- props: Record;
- type: "host";
- };
- };
- "trplx:requestBlurSceneObject": undefined;
- "trplx:requestCameraTypeChange": {
- type: "perspective" | "orthographic";
- };
- "trplx:requestDeleteSceneObject": {
- column: number;
- line: number;
- parentPath: string;
- };
- "trplx:requestFocusSceneObject": {
- column: number;
- line: number;
- parentPath: string;
- path: string;
- };
- "trplx:requestJumpToSceneObject": undefined;
- "trplx:requestNavigateToScene":
- | {
- encodedProps: string;
- exportName: string;
- path: string;
- }
- | undefined;
- "trplx:requestPersistSceneObjectProp": {
- column: number;
- line: number;
- path: string;
- propName: string;
- propValue: unknown;
- };
- "trplx:requestRefresh": { hard?: boolean };
- "trplx:requestReset": undefined;
- "trplx:requestResetSceneObjectProp": {
- column: number;
- line: number;
- path: string;
- propName: string;
- };
- "trplx:requestRestoreSceneObject": {
- column: number;
- line: number;
- parentPath: string;
- };
- "trplx:requestSceneObjectPropValue": {
- column: number;
- line: number;
- path: string;
- propName: string;
- };
- "trplx:requestSetSceneObjectProp": {
- column: number;
- line: number;
- path: string;
- propName: string;
- propValue: unknown;
- };
- "trplx:requestTransformChange": {
- mode: "translate" | "scale" | "rotate";
- };
-}
-
-export interface HostSendEventResponse {
- "trplx:requestAction": void;
- "trplx:requestAddNewComponent": void;
- "trplx:requestBlurSceneObject": void;
- "trplx:requestCameraTypeChange": void;
- "trplx:requestDeleteSceneObject": void;
- "trplx:requestFocusSceneObject": void;
- "trplx:requestJumpToSceneObject": void;
- "trplx:requestNavigateToScene": void;
- "trplx:requestPersistSceneObjectProp": void;
- "trplx:requestRefresh": void;
- "trplx:requestReset": void;
- "trplx:requestResetSceneObjectProp": void;
- "trplx:requestRestoreSceneObject": void;
- "trplx:requestSceneObjectPropValue": { value: unknown };
- "trplx:requestSetSceneObjectProp": void;
- "trplx:requestTransformChange": void;
-}
diff --git a/packages/bridge/tsconfig.json b/packages/bridge/tsconfig.json
deleted file mode 100644
index e3b45f2a..00000000
--- a/packages/bridge/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "../../.tsconfig/react-library.json",
- "include": ["."],
- "exclude": ["dist", "build", "node_modules"],
- "compilerOptions": {
- "baseUrl": ".",
- "outDir": "./dist"
- }
-}
diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md
deleted file mode 100644
index 0b5702b5..00000000
--- a/packages/editor/CHANGELOG.md
+++ /dev/null
@@ -1,897 +0,0 @@
-# @triplex/editor
-
-## 0.58.2
-
-### Patch Changes
-
-- 85447c2: Add halloween template for project initialization.
-- 85447c2: Upgrade three.js.
-- b5247c2: Apply lint and prettier fixes.
-- Updated dependencies [b5247c2]
- - @triplex/ws-client@0.58.2
- - @triplex/bridge@0.58.2
-
-## 0.58.1
-
-### Patch Changes
-
-- e645e5c: Fix provider ui not respecting default props.
-- f1656e0: Provider config now takes up slightly more space.
- - @triplex/ws-client@0.58.1
- - @triplex/bridge@0.58.1
-
-## 0.58.0
-
-### Minor Changes
-
-- 37bf36d: Add provider props as config to the ui.
-- 3e1e081: Separate soft refresh from hard refresh.
-
-### Patch Changes
-
-- Updated dependencies [3e1e081]
- - @triplex/bridge@0.58.0
- - @triplex/ws-client@0.58.0
-
-## 0.57.2
-
-### Patch Changes
-
-- f5bbeda: Literal union input now supports boolean literals.
-- f5bbeda: Fix server throwing when symbols for jsx elements were not resolved.
- - @triplex/ws-client@0.57.2
- - @triplex/bridge@0.57.2
-
-## 0.57.1
-
-### Patch Changes
-
-- @triplex/bridge@0.57.1
-- @triplex/ws-client@0.57.1
-
-## 0.57.0
-
-### Minor Changes
-
-- 5c1fc3d: Add editing child jsx elements through the Triplex UI.
-- 628646e: Context panel now has a filter for props.
-- 7673ae8: A search input filter is now available when opening a component.
-- 2b61384: Adding an asset is now contextual, the original button adds to the
- open component, while the add buttons on each element in the left scene panel
- add to it as a child.
-
-### Patch Changes
-
-- 046cf78: Error notification is now displayed in the bottom left and is
- emphasized less.
-- 2b61384: When adding new elements to the scene the left scene panel now
- scrolls to the added element if needed.
-- 628646e: Inputs can now have their content selected with the select all
- command (cmd + a).
-- Updated dependencies [5c1fc3d]
-- Updated dependencies [2b61384]
- - @triplex/bridge@0.57.0
- - @triplex/ws-client@0.57.0
-
-## 0.56.1
-
-### Patch Changes
-
-- @triplex/ws-client@0.56.1
-- @triplex/bridge@0.56.1
-
-## 0.56.0
-
-### Minor Changes
-
-- 463789f: Adds end-to-end typesafe ws router.
-- 32a110f: Add top-level scene component to the scene panel. When selected users
- can modify the props during their seession to see what happens.
-- 47483b9: The data that powers the context panel props is now sourced from
- types first instead of defined props first, resulting in tuple type data no
- longer being lost after a prop has been set.
-
-### Patch Changes
-
-- d674f26: Color input can now be cleared when not required.
-- 47483b9: Tuple input no longer fires when required values are only partially
- filled out.
-- 2e53a2e: Turn off type declaration maps.
-- Updated dependencies [463789f]
-- Updated dependencies [5f7e78f]
-- Updated dependencies [32a110f]
-- Updated dependencies [2e53a2e]
- - @triplex/ws-client@0.56.0
- - @triplex/bridge@0.56.0
-
-## 0.55.3
-
-### Patch Changes
-
-- @triplex/bridge@0.55.3
-- @triplex/ws-client@0.55.3
-
-## 0.55.2
-
-### Patch Changes
-
-- @triplex/bridge@0.55.2
-- @triplex/ws-client@0.55.2
-
-## 0.55.1
-
-### Patch Changes
-
-- ea86fdc: Add license banner.
-- b3d2fa9: Number input no longer calls change and confirm handlers if the value
- is outside the min/max range.
-- Updated dependencies [ea86fdc]
- - @triplex/ws-client@0.55.1
- - @triplex/bridge@0.55.1
-
-## 0.55.0
-
-### Minor Changes
-
-- 3be2782: Add support for adding a gltf static asset to the scene.
-- b6970aa: Adds prop tags to context to be picked up by inputs.
-- ab909b4: Static assets are now available through the assets drawer.
-- 4fa9018: The number input has been re-written to improve its UX.
-- 44faed1: Jsdoc tags are now returned in the jsx element type response.
-- b6970aa: Number input can now have a min/max value set using `@min` and `@max`
- jsdoc tags respectively. E.g. `@min 1` will cap the input value to 1.
-
-### Patch Changes
-
-- Updated dependencies [ab909b4]
- - @triplex/ws-client@0.55.0
- - @triplex/bridge@0.55.0
-
-## 0.54.2
-
-### Patch Changes
-
-- Updated dependencies [a060d2c]
- - @triplex/ws-client@0.54.2
- - @triplex/bridge@0.54.2
-
-## 0.54.1
-
-### Patch Changes
-
-- d58e0b0: During save a route transition will only occur if saving the file to
- another path.
-- 8afea84: Focus state is now handled across the app.
-- cdd6234: Delete and undo/redo actions are no longer double fired when using
- the hotkey in the editor.
- - @triplex/bridge@0.54.1
- - @triplex/ws-client@0.54.1
-
-## 0.54.0
-
-### Minor Changes
-
-- 8fad65a: Adds camera type to controls menu, allowing you to switch between
- perspective and orthographic camera.
-- e0038f6: Add support for viewing through a user land camera.
-
-### Patch Changes
-
-- e0038f6: Disable enter component for node modules dependencies.
-- Updated dependencies [8fad65a]
-- Updated dependencies [e0038f6]
- - @triplex/bridge@0.54.0
- - @triplex/ws-client@0.54.0
-
-## 0.53.1
-
-### Patch Changes
-
-- @triplex/bridge@0.53.1
-- @triplex/ws-client@0.53.1
-
-## 0.53.0
-
-### Minor Changes
-
-- c71412b: Adds refresh scene action available in the File menubar and through
- cmd/ctrl + r.
-
-### Patch Changes
-
-- aa3a982: View logs button no longer is disabled during project creation.
-- aa3a982: React and React Three Fiber are now peer dependencies.
-- aa3a982: Fixed three peer dependency not being loose enough and
- react-three-fiber and react being missing from peer dependencies.
-- bddac75: Welcome screen version number now positioned depending on OS.
-- Updated dependencies [aa3a982]
-- Updated dependencies [c71412b]
- - @triplex/ws-client@0.53.0
- - @triplex/bridge@0.53.0
-
-## 0.52.0
-
-### Minor Changes
-
-- 48016ba: Rotation props are now displayed as degrees in the UI and saved to
- code as radians. Previously it was all radians which was confusing for pretty
- much everyone.
-- fe90482: Logs are now accessible through the View > Logs menubar action.
-- 8d532f5: Editor now shows build time and runtime errors in an error overlay.
-
-### Patch Changes
-
-- 120f9ef: When updating array inputs undefined optional values are now ignored
- and discarded.
-- Updated dependencies [8d532f5]
- - @triplex/bridge@0.52.0
- - @triplex/ws-client@0.52.0
-
-## 0.51.1
-
-### Patch Changes
-
-- @triplex/bridge@0.51.1
-- @triplex/ws-client@0.51.1
-
-## 0.51.0
-
-### Minor Changes
-
-- b61dc2a: The editor menu bar is now displayed in the title bar for Windows and
- Node.js.
-
-### Patch Changes
-
-- b61dc2a: Hotkeys on Windows are now title case.
-- b61dc2a: Menu bar events now originate from the editor source instead of being
- some in the electron app and some in the editor.
-- c97e359: Inputs no longer call change and confirm handlers with `undefined`
- values when required.
- - @triplex/bridge@0.51.0
- - @triplex/ws-client@0.51.0
-
-## 0.50.1
-
-### Patch Changes
-
-- @triplex/bridge@0.50.1
-- @triplex/ws-client@0.50.1
-
-## 0.50.0
-
-### Minor Changes
-
-- 8ea575b: Built output is now mangled.
-
-### Patch Changes
-
-- Updated dependencies [8ea575b]
- - @triplex/bridge@0.50.0
- - @triplex/ws-client@0.50.0
-
-## 0.49.0
-
-### Minor Changes
-
-- 3eae131: Welcome screen now shows a progress bar when installing node modules.
-- 8c5611d: Adds create project action to the welcome screen.
-- 3eae131: Welcome screen now is draggable using the top invisible title bar.
-
-### Patch Changes
-
-- @triplex/bridge@0.49.0
-- @triplex/ws-client@0.49.0
-
-## 0.48.0
-
-### Minor Changes
-
-- 6fe34af: Windows support is here. Now Triplex cli and electron can be ran on
- Windows, as well as the local dev loop now being functional.
-
-### Patch Changes
-
-- @triplex/bridge@0.48.0
-- @triplex/ws-client@0.48.0
-
-## 0.47.0
-
-### Minor Changes
-
-- daa2697: Adds a welcome screen to the electron app.
-- 1fc7657: Menu bar is now native when ran in the electron app.
-- 1fc7657: Electron app now uses a custom title bar.
-- e8cf76f: Adds native save dialog support.
-- 1fc7657: Window title now uses both the folder name and file name if open.
-- 4164026: Undo/redo menu items now correctly display as enabled or disabled
- when appropriate.
-
-### Patch Changes
-
-- 4164026: Editor is now typechecked again.
-- e8cf76f: When no file is open irrelevant menu items are now disabled.
- - @triplex/bridge@0.47.0
- - @triplex/ws-client@0.47.0
-
-## 0.46.4
-
-### Patch Changes
-
-- @triplex/bridge@0.46.4
-- @triplex/ws-client@0.46.4
-
-## 0.46.3
-
-### Patch Changes
-
-- @triplex/bridge@0.46.3
-- @triplex/ws-client@0.46.3
-
-## 0.46.2
-
-### Patch Changes
-
-- @triplex/bridge@0.46.2
-- @triplex/ws-client@0.46.2
-
-## 0.46.1
-
-### Patch Changes
-
-- @triplex/bridge@0.46.1
-- @triplex/ws-client@0.46.1
-
-## 0.46.0
-
-### Patch Changes
-
-- @triplex/bridge@0.46.0
-- @triplex/ws-client@0.46.0
-
-## 0.45.1
-
-### Patch Changes
-
-- @triplex/bridge@0.45.1
-- @triplex/ws-client@0.45.1
-
-## 0.45.0
-
-### Patch Changes
-
-- @triplex/bridge@0.45.0
-- @triplex/ws-client@0.45.0
-
-## 0.44.0
-
-### Minor Changes
-
-- 0242833: Scene now removes intermediate state when resetting.
-- 56b17f0: Adds filter for add element drawer.
-- 4d8d9cc: Builds are now minified.
-- 557648e: Editor has been extracted out of the client dev server and now is
- bundled when published to npm.
-
-### Patch Changes
-
-- Updated dependencies [0242833]
-- Updated dependencies [4d8d9cc]
-- Updated dependencies [557648e]
- - @triplex/bridge@0.44.0
- - @triplex/ws-client@0.44.0
-
-## 0.43.0
-
-### Minor Changes
-
-- 6dfb22d: Save as action now available in the menubar. Use to save the current
- open file to another location.
-- 6dfb22d: Scroll container thumb scroll areas now take up less space.
-- 6dfb22d: Create a component in the current open file through the component
- switcher.
-- de54812: Color inputs now show a transparent background when undefined.
-- b7bbeba: Deleting the selected element with backspace now works when focused
- on any element other than an input.
-- 6dfb22d: A component switcher is now available in the left panel, use it to
- quickly switch between components in the open file.
-- 6dfb22d: The browser tab title now changes when there are unsaved changes.
-- b7bbeba: String and numbers in props now can have undefined default values.
-- de54812: Prop inputs now are able to be cleared through the ui.
-- de54812: Context panel tuple props now show labels when available.
-- de54812: Checkbox now renders using a custom icon.
-- b7bbeba: When adding a new element to the scene if you have a selection it
- will be added as a child. If you have no selection it will be added to the
- root component.
-- 01cd388: Adds context panel indicator to the add component drawer when an
- element is selected.
-- facc6aa: Saving a new component now prompts for a component name.
-- de54812: Fixed save prop serializing undefined to null.
-- 01cd388: Fixes the context panel unexpectedly when closing the color picker
- with escape.
-
-### Patch Changes
-
-- Updated dependencies [b7bbeba]
- - @triplex/bridge@0.43.0
- - @triplex/ws-client@0.43.0
-
-## 0.42.0
-
-### Patch Changes
-
-- @triplex/bridge@0.42.0
-- @triplex/ws-client@0.42.0
-
-## 0.41.0
-
-### Minor Changes
-
-- 5d161d8: The editor panels are now displayed on a single flex layout.
-
-### Patch Changes
-
-- @triplex/bridge@0.41.0
-- @triplex/ws-client@0.41.0
-
-## 0.40.0
-
-### Minor Changes
-
-- a2a2f4b: Removes usage of r3f internals.
-- a2a2f4b: Fixes union input accidentally having default value being applied
- when it shouldn't.
-- dac7c76: Selection for scene objects is now more resilient being able to be
- set before scene objects are actually available.
-- bfb0f7a: Adds an error boundary ui to replace the basic error text version.
-- ee2494b: When clicking ide links such as view source websocket connections no
- longer close.
-
-### Patch Changes
-
-- Updated dependencies [ee2494b]
- - @triplex/ws-client@0.40.0
- - @triplex/bridge@0.40.0
-
-## 0.39.0
-
-### Minor Changes
-
-- ca9807e: New files can now be created through the file menu.
-- ca9807e: After adding a component it will now be automatically focused.
-- ca9807e: Union input now correctly picks up default value.
-
-### Patch Changes
-
-- @triplex/bridge@0.39.0
-- @triplex/ws-client@0.39.0
-
-## 0.38.0
-
-### Patch Changes
-
-- @triplex/bridge@0.38.0
-- @triplex/ws-client@0.38.0
-
-## 0.37.0
-
-### Minor Changes
-
-- 23fe64a: Adds delete scene object. Access through the context panel when
- focusing on a scene object.
-
-### Patch Changes
-
-- Updated dependencies [23fe64a]
-- Updated dependencies [1a2ecea]
- - @triplex/bridge@0.37.0
- - @triplex/ws-client@0.37.0
-
-## 0.36.0
-
-### Patch Changes
-
-- @triplex/bridge@0.36.0
-- @triplex/ws-client@0.36.0
-
-## 0.35.0
-
-### Minor Changes
-
-- e53a703: Prop font size in the context panel has been reduced.
-- e53a703: Emissive prop now considered a color.
-
-### Patch Changes
-
-- @triplex/bridge@0.35.0
-- @triplex/ws-client@0.35.0
-
-## 0.34.0
-
-### Minor Changes
-
-- 2a64658: Prop descriptions are now viewable in the context panel when hovering
- over prop names.
-- 2a64658: The context panel now displays all available props on a component
- even if they aren't yet declared thanks to the TypeScript compiler and
- ts-morph. Not all prop types are supported currently, if you have one that you
- expected to be available but isn't please reach out.
-
-### Patch Changes
-
-- Updated dependencies [2a64658]
- - @triplex/ws-client@0.34.0
- - @triplex/bridge@0.34.0
-
-## 0.33.0
-
-### Minor Changes
-
-- 1067d23: Adds transform controls to the ui.
-
-### Patch Changes
-
-- Updated dependencies [1067d23]
- - @triplex/bridge@0.33.0
- - @triplex/ws-client@0.33.0
-
-## 0.32.0
-
-### Minor Changes
-
-- 73d9e8c: Inputs no longer trigger dirty scene state if their value hasn't
- changed.
-- c87a5f3: Undo/redo now available. When manipulating the scene through
- transform controls or the context panel each persisted manipulation will be
- able to be undone (and redone) using hotkeys and the edit menu actions.
-- c87a5f3: Saving with hotkey is now available when focus is on the ui.
-- c87a5f3: Adds reset command. Use this to throw away all unsaved changes in the
- scene.
-
-### Patch Changes
-
-- Updated dependencies [c87a5f3]
- - @triplex/bridge@0.32.0
- - @triplex/ws-client@0.32.0
-
-## 0.31.0
-
-### Minor Changes
-
-- 5ac3a26: UI has been darkened and borders have been deemphasized.
-- a1e3127: When source changes ui now reflects the updated value.
-- 48002a7: Array input no longer caches its value which resulted in unexpected
- bugs when transforming in scene and then through the ui.
-
-### Patch Changes
-
-- @triplex/bridge@0.31.0
-- @triplex/ws-client@0.31.0
-
-## 0.30.0
-
-### Minor Changes
-
-- 0bb6119: Adds support for updating scene objects through the context panel.
-- 0bb6119: Extract inputs to their own custom components.
-- 0bb6119: Fix color input not showing for various color inputs.
-
-### Patch Changes
-
-- Updated dependencies [0bb6119]
- - @triplex/bridge@0.30.0
- - @triplex/ws-client@0.30.0
-
-## 0.29.0
-
-### Minor Changes
-
-- 0d83ef2: Scene drawer now has correct padding and is increased in width.
-- 0d83ef2: The catch all prop field now has capped height stopping it from
- looking ridiculous.
-
-### Patch Changes
-
-- @triplex/bridge@0.29.0
-- @triplex/ws-client@0.29.0
-
-## 0.28.0
-
-### Minor Changes
-
-- aa1aa8c: Scene transformation using ts-morph has been replaced with Babel
- significantly speeding up initial load and saving. The need for the
- `.triplex/tmp` folder is now gone and thus no longer used.
-- aa1aa8c: Line and column numbers for scene objects have been corrected and are
- now consistent across editor, scene, and server.
-- aa1aa8c: Scene drawer now shows loading text when appropriate.
-
-### Patch Changes
-
-- @triplex/bridge@0.28.0
-- @triplex/ws-client@0.28.0
-
-## 0.27.0
-
-### Minor Changes
-
-- fa35cde: Fixes UI scrolling and contrast bugs.
-- 9b1d135: Increased gutters in the scene panel list as well as fixing the
- variable width in the context panel.
-- 246217f: Text contrast in the scene and context panel have been improved.
-- e5a3419: Context panel now supports more prop types.
-
-### Patch Changes
-
-- @triplex/bridge@0.27.0
-- @triplex/ws-client@0.27.0
-
-## 0.26.0
-
-### Minor Changes
-
-- 785050d: Adds unsaved indicator to the editor.
-- 71374c9: Scene, context, and open scene containers now scroll when overflowing
- with content.
-
-### Patch Changes
-
-- Updated dependencies [785050d]
- - @triplex/ws-client@0.26.0
- - @triplex/bridge@0.26.0
-
-## 0.25.0
-
-### Patch Changes
-
-- @triplex/bridge@0.25.0
-- @triplex/ws-client@0.25.0
-
-## 0.24.0
-
-### Patch Changes
-
-- @triplex/bridge@0.24.0
-- @triplex/ws-client@0.24.0
-
-## 0.23.0
-
-### Patch Changes
-
-- @triplex/bridge@0.23.0
-- @triplex/ws-client@0.23.0
-
-## 0.22.0
-
-### Minor Changes
-
-- aa9c9ae: Lighten selected state.
-
-### Patch Changes
-
-- @triplex/bridge@0.22.0
-- @triplex/ws-client@0.22.0
-
-## 0.21.0
-
-### Patch Changes
-
-- @triplex/bridge@0.21.0
-- @triplex/ws-client@0.21.0
-
-## 0.20.0
-
-### Minor Changes
-
-- 1c9771d: Named exports are now able to be opened by the editor.
-- 1c9771d: Scene drawer now shows named exports from scenes.
-- 1c9771d: Focus events now only use line and column numbers.
-
-### Patch Changes
-
-- Updated dependencies [1c9771d]
- - @triplex/bridge@0.20.0
- - @triplex/ws-client@0.20.0
-
-## 0.19.0
-
-### Patch Changes
-
-- @triplex/bridge@0.19.0
-- @triplex/ws-client@0.19.0
-
-## 0.18.0
-
-### Patch Changes
-
-- @triplex/bridge@0.18.0
-- @triplex/ws-client@0.18.0
-
-## 0.17.0
-
-### Patch Changes
-
-- @triplex/bridge@0.17.0
-- @triplex/ws-client@0.17.0
-
-## 0.16.0
-
-### Minor Changes
-
-- e7c026b: Scene drawer no-longer stays open when selecting a scene.
-- 7ff35f3: Context panel no longer throws when navigating between scene and a
- scene object is selected.
-- e7c026b: Scene panel now shows correctly nested jsx elements.
-- e7c026b: Disabled menu items are now actually disabled.
-- 7ff35f3: Upgrades @react-three/fiber to latest.
-- 7ff35f3: Navigating to host elements is no longer possible (as there is
- nowhere to navigate to).
-- 2fa7c45: Adds author field to package.json.
-
-### Patch Changes
-
-- Updated dependencies [d8e1602]
-- Updated dependencies [7ff35f3]
-- Updated dependencies [2fa7c45]
- - @triplex/bridge@0.16.0
- - @triplex/ws-client@0.16.0
-
-## 0.15.0
-
-### Minor Changes
-
-- e54e0f8: Editor now has a select menu with useful actions when a scene object
- is selected.
-- e54e0f8: Bridge events now flow unidirectionally enabling the editor ui to
- initiate events to the scene, such as navigate and focus.
-
-### Patch Changes
-
-- Updated dependencies [e54e0f8]
- - @triplex/bridge@0.15.0
- - @triplex/ws-client@0.15.0
-
-## 0.14.0
-
-### Minor Changes
-
-- 7a8083c: The open rpc has been added back to prevent the "flash of no scene"
- when transitioning between scenes for the first time.
-
-### Patch Changes
-
-- @triplex/bridge@0.14.0
-- @triplex/ws-client@0.14.0
-
-## 0.13.0
-
-### Minor Changes
-
-- cfbd47b: When transitioning between scenes there is no longer a flash of
- hidden scene objects.
-- 969feab: Removes unneeded fetch calls.
-- cc917d7: Adds usage of ws-client pkg.
-- 969feab: Adds react suspense powered websocket abstraction.
-- a4d6882: Adds context panel for selected scene objects.
-- 99075ff: Adds error boundaries so the app doesn't blow up when a scene isn't
- found.
-- cfbd47b: Scene meta has been extrated into a common hook.
-- 969feab: Scene list and scene components ui now fetch data using the websocket
- client.
-
-### Patch Changes
-
-- Updated dependencies [a4d6882]
-- Updated dependencies [cc917d7]
- - @triplex/bridge@0.7.0
- - @triplex/ws-client@0.1.0
-
-## 0.12.0
-
-### Minor Changes
-
-- 55f0206: Fixed focus and blur events between the scene and the editor.
-- 55f0206: Scene components now appear nested when children of other components
- in the UI.
-
-## 0.11.0
-
-### Minor Changes
-
-- 3c725bc: Force release all packages.
-
-### Patch Changes
-
-- Updated dependencies [3c725bc]
- - @triplex/bridge@0.6.0
-
-## 0.10.0
-
-### Minor Changes
-
-- a32c72e: Adds the scene component list to the sidebar with the ability to
- focus scene objects on click. Scene components in this list are also selected
- when focusing scene objects in the scene.
-
-## 0.9.0
-
-### Minor Changes
-
-- ac9624f: Fixes client/host race condition where host would send events before
- the client has connected.
-- 7db42bd: Adds open scene drawer.
-
-### Patch Changes
-
-- Updated dependencies [ac9624f]
- - @triplex/bridge@0.5.0
-
-## 0.8.0
-
-### Minor Changes
-
-- 387f6cd: Editor now able to use tailwindcss during dev, which is compiled away
- when packaged to npm.
-- 387f6cd: Adds a menu bar to the editor.
-
-## 0.7.0
-
-### Minor Changes
-
-- 56dde00: Fixes publish config main field to point to the correct location.
-
-## 0.6.0
-
-### Minor Changes
-
-- c84a8ca: Package now declares the main field.
-
-## 0.5.0
-
-### Minor Changes
-
-- c8c4a55: Fixes scene frame so it can hot module reload.
-
-## 0.4.0
-
-### Minor Changes
-
-- b144bb1: Package `build` now use `swc` and `tsc` directly.
-
-### Patch Changes
-
-- Updated dependencies [b144bb1]
- - @triplex/bridge@0.4.0
-
-## 0.3.0
-
-### Minor Changes
-
-- bbc457e: Fixes some bugs preventing triplex from being able to be ran via cli.
-
-### Patch Changes
-
-- Updated dependencies [bbc457e]
- - @triplex/bridge@0.3.0
-
-## 0.2.0
-
-### Minor Changes
-
-- 08a03af: Fixes publish to build before pushing.
-
-### Patch Changes
-
-- Updated dependencies [08a03af]
- - @triplex/bridge@0.2.0
-
-## 0.1.0
-
-### Minor Changes
-
-- 9c120b4: Initial release.
-
-### Patch Changes
-
-- Updated dependencies [9c120b4]
- - @triplex/bridge@0.1.0
diff --git a/packages/editor/LICENSE b/packages/editor/LICENSE
deleted file mode 100644
index 741b8fab..00000000
--- a/packages/editor/LICENSE
+++ /dev/null
@@ -1,632 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
-Copyright (C) 2007 Free Software Foundation, Inc. Everyone is
-permitted to copy and distribute verbatim copies of this license document, but
-changing it is not allowed.
-
- Preamble
-
-The GNU General Public License is a free, copyleft license for software and
-other kinds of works.
-
-The licenses for most software and other practical works are designed to take
-away your freedom to share and change the works. By contrast, the GNU General
-Public License is intended to guarantee your freedom to share and change all
-versions of a program--to make sure it remains free software for all its users.
-We, the Free Software Foundation, use the GNU General Public License for most of
-our software; it applies also to any other work released this way by its
-authors. You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom to
-distribute copies of free software (and charge for them if you wish), that you
-receive source code or can get it if you want it, that you can change the
-software or use pieces of it in new free programs, and that you know you can do
-these things.
-
-To protect your rights, we need to prevent others from denying you these rights
-or asking you to surrender the rights. Therefore, you have certain
-responsibilities if you distribute copies of the software, or if you modify it:
-responsibilities to respect the freedom of others.
-
-For example, if you distribute copies of such a program, whether gratis or for a
-fee, you must pass on to the recipients the same freedoms that you received. You
-must make sure that they, too, receive or can get the source code. And you must
-show them these terms so they know their rights.
-
-Developers that use the GNU GPL protect your rights with two steps: (1) assert
-copyright on the software, and (2) offer you this License giving you legal
-permission to copy, distribute and/or modify it.
-
-For the developers' and authors' protection, the GPL clearly explains that there
-is no warranty for this free software. For both users' and authors' sake, the
-GPL requires that modified versions be marked as changed, so that their problems
-will not be attributed erroneously to authors of previous versions.
-
-Some devices are designed to deny users access to install or run modified
-versions of the software inside them, although the manufacturer can do so. This
-is fundamentally incompatible with the aim of protecting users' freedom to
-change the software. The systematic pattern of such abuse occurs in the area of
-products for individuals to use, which is precisely where it is most
-unacceptable. Therefore, we have designed this version of the GPL to prohibit
-the practice for those products. If such problems arise substantially in other
-domains, we stand ready to extend this provision to those domains in future
-versions of the GPL, as needed to protect the freedom of users.
-
-Finally, every program is threatened constantly by software patents. States
-should not allow patents to restrict development and use of software on
-general-purpose computers, but in those that do, we wish to avoid the special
-danger that patents applied to a free program could make it effectively
-proprietary. To prevent this, the GPL assures that patents cannot be used to
-render the program non-free.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
- TERMS AND CONDITIONS
-
-0. Definitions.
-
-"This License" refers to version 3 of the GNU General Public License.
-
-"Copyright" also means copyright-like laws that apply to other kinds of works,
-such as semiconductor masks.
-
-"The Program" refers to any copyrightable work licensed under this License. Each
-licensee is addressed as "you". "Licensees" and "recipients" may be individuals
-or organizations.
-
-To "modify" a work means to copy from or adapt all or part of the work in a
-fashion requiring copyright permission, other than the making of an exact copy.
-The resulting work is called a "modified version" of the earlier work or a work
-"based on" the earlier work.
-
-A "covered work" means either the unmodified Program or a work based on the
-Program.
-
-To "propagate" a work means to do anything with it that, without permission,
-would make you directly or secondarily liable for infringement under applicable
-copyright law, except executing it on a computer or modifying a private copy.
-Propagation includes copying, distribution (with or without modification),
-making available to the public, and in some countries other activities as well.
-
-To "convey" a work means any kind of propagation that enables other parties to
-make or receive copies. Mere interaction with a user through a computer network,
-with no transfer of a copy, is not conveying.
-
-An interactive user interface displays "Appropriate Legal Notices" to the extent
-that it includes a convenient and prominently visible feature that (1) displays
-an appropriate copyright notice, and (2) tells the user that there is no
-warranty for the work (except to the extent that warranties are provided), that
-licensees may convey the work under this License, and how to view a copy of this
-License. If the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-1. Source Code.
-
-The "source code" for a work means the preferred form of the work for making
-modifications to it. "Object code" means any non-source form of a work.
-
-A "Standard Interface" means an interface that either is an official standard
-defined by a recognized standards body, or, in the case of interfaces specified
-for a particular programming language, one that is widely used among developers
-working in that language.
-
-The "System Libraries" of an executable work include anything, other than the
-work as a whole, that (a) is included in the normal form of packaging a Major
-Component, but which is not part of that Major Component, and (b) serves only to
-enable use of the work with that Major Component, or to implement a Standard
-Interface for which an implementation is available to the public in source code
-form. A "Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system (if any) on
-which the executable work runs, or a compiler used to produce the work, or an
-object code interpreter used to run it.
-
-The "Corresponding Source" for a work in object code form means all the source
-code needed to generate, install, and (for an executable work) run the object
-code and to modify the work, including scripts to control those activities.
-However, it does not include the work's System Libraries, or general-purpose
-tools or generally available free programs which are used unmodified in
-performing those activities but which are not part of the work. For example,
-Corresponding Source includes interface definition files associated with source
-files for the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require, such as by
-intimate data communication or control flow between those subprograms and other
-parts of the work.
-
-The Corresponding Source need not include anything that users can regenerate
-automatically from other parts of the Corresponding Source.
-
-The Corresponding Source for a work in source code form is that same work.
-
-2. Basic Permissions.
-
-All rights granted under this License are granted for the term of copyright on
-the Program, and are irrevocable provided the stated conditions are met. This
-License explicitly affirms your unlimited permission to run the unmodified
-Program. The output from running a covered work is covered by this License only
-if the output, given its content, constitutes a covered work. This License
-acknowledges your rights of fair use or other equivalent, as provided by
-copyright law.
-
-You may make, run and propagate covered works that you do not convey, without
-conditions so long as your license otherwise remains in force. You may convey
-covered works to others for the sole purpose of having them make modifications
-exclusively for you, or provide you with facilities for running those works,
-provided that you comply with the terms of this License in conveying all
-material for which you do not control copyright. Those thus making or running
-the covered works for you must do so exclusively on your behalf, under your
-direction and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-Conveying under any other circumstances is permitted solely under the conditions
-stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
-
-3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-No covered work shall be deemed part of an effective technological measure under
-any applicable law fulfilling obligations under article 11 of the WIPO copyright
-treaty adopted on 20 December 1996, or similar laws prohibiting or restricting
-circumvention of such measures.
-
-When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention is
-effected by exercising rights under this License with respect to the covered
-work, and you disclaim any intention to limit operation or modification of the
-work as a means of enforcing, against the work's users, your or third parties'
-legal rights to forbid circumvention of technological measures.
-
-4. Conveying Verbatim Copies.
-
-You may convey verbatim copies of the Program's source code as you receive it,
-in any medium, provided that you conspicuously and appropriately publish on each
-copy an appropriate copyright notice; keep intact all notices stating that this
-License and any non-permissive terms added in accord with section 7 apply to the
-code; keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-You may charge any price or no price for each copy that you convey, and you may
-offer support or warranty protection for a fee.
-
-5. Conveying Modified Source Versions.
-
-You may convey a work based on the Program, or the modifications to produce it
-from the Program, in the form of source code under the terms of section 4,
-provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
-A compilation of a covered work with other separate and independent works, which
-are not by their nature extensions of the covered work, and which are not
-combined with it such as to form a larger program, in or on a volume of a
-storage or distribution medium, is called an "aggregate" if the compilation and
-its resulting copyright are not used to limit the access or legal rights of the
-compilation's users beyond what the individual works permit. Inclusion of a
-covered work in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-6. Conveying Non-Source Forms.
-
-You may convey a covered work in object code form under the terms of sections 4
-and 5, provided that you also convey the machine-readable Corresponding Source
-under the terms of this License, in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
-A separable portion of the object code, whose source code is excluded from the
-Corresponding Source as a System Library, need not be included in conveying the
-object code work.
-
-A "User Product" is either (1) a "consumer product", which means any tangible
-personal property which is normally used for personal, family, or household
-purposes, or (2) anything designed or sold for incorporation into a dwelling. In
-determining whether a product is a consumer product, doubtful cases shall be
-resolved in favor of coverage. For a particular product received by a particular
-user, "normally used" refers to a typical or common use of that class of
-product, regardless of the status of the particular user or of the way in which
-the particular user actually uses, or expects or is expected to use, the
-product. A product is a consumer product regardless of whether the product has
-substantial commercial, industrial or non-consumer uses, unless such uses
-represent the only significant mode of use of the product.
-
-"Installation Information" for a User Product means any methods, procedures,
-authorization keys, or other information required to install and execute
-modified versions of a covered work in that User Product from a modified version
-of its Corresponding Source. The information must suffice to ensure that the
-continued functioning of the modified object code is in no case prevented or
-interfered with solely because modification has been made.
-
-If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as part of a
-transaction in which the right of possession and use of the User Product is
-transferred to the recipient in perpetuity or for a fixed term (regardless of
-how the transaction is characterized), the Corresponding Source conveyed under
-this section must be accompanied by the Installation Information. But this
-requirement does not apply if neither you nor any third party retains the
-ability to install modified object code on the User Product (for example, the
-work has been installed in ROM).
-
-The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates for a
-work that has been modified or installed by the recipient, or for the User
-Product in which it has been modified or installed. Access to a network may be
-denied when the modification itself materially and adversely affects the
-operation of the network or violates the rules and protocols for communication
-across the network.
-
-Corresponding Source conveyed, and Installation Information provided, in accord
-with this section must be in a format that is publicly documented (and with an
-implementation available to the public in source code form), and must require no
-special password or key for unpacking, reading or copying.
-
-7. Additional Terms.
-
-"Additional permissions" are terms that supplement the terms of this License by
-making exceptions from one or more of its conditions. Additional permissions
-that are applicable to the entire Program shall be treated as though they were
-included in this License, to the extent that they are valid under applicable
-law. If additional permissions apply only to part of the Program, that part may
-be used separately under those permissions, but the entire Program remains
-governed by this License without regard to the additional permissions.
-
-When you convey a copy of a covered work, you may at your option remove any
-additional permissions from that copy, or from any part of it. (Additional
-permissions may be written to require their own removal in certain cases when
-you modify the work.) You may place additional permissions on material, added by
-you to a covered work, for which you have or can give appropriate copyright
-permission.
-
-Notwithstanding any other provision of this License, for material you add to a
-covered work, you may (if authorized by the copyright holders of that material)
-supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
-All other non-permissive additional terms are considered "further restrictions"
-within the meaning of section 10. If the Program as you received it, or any part
-of it, contains a notice stating that it is governed by this License along with
-a term that is a further restriction, you may remove that term. If a license
-document contains a further restriction but permits relicensing or conveying
-under this License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does not survive
-such relicensing or conveying.
-
-If you add terms to a covered work in accord with this section, you must place,
-in the relevant source files, a statement of the additional terms that apply to
-those files, or a notice indicating where to find the applicable terms.
-
-Additional terms, permissive or non-permissive, may be stated in the form of a
-separately written license, or stated as exceptions; the above requirements
-apply either way.
-
-8. Termination.
-
-You may not propagate or modify a covered work except as expressly provided
-under this License. Any attempt otherwise to propagate or modify it is void, and
-will automatically terminate your rights under this License (including any
-patent licenses granted under the third paragraph of section 11).
-
-However, if you cease all violation of this License, then your license from a
-particular copyright holder is reinstated (a) provisionally, unless and until
-the copyright holder explicitly and finally terminates your license, and (b)
-permanently, if the copyright holder fails to notify you of the violation by
-some reasonable means prior to 60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is reinstated
-permanently if the copyright holder notifies you of the violation by some
-reasonable means, this is the first time you have received notice of violation
-of this License (for any work) from that copyright holder, and you cure the
-violation prior to 30 days after your receipt of the notice.
-
-Termination of your rights under this section does not terminate the licenses of
-parties who have received copies or rights from you under this License. If your
-rights have been terminated and not permanently reinstated, you do not qualify
-to receive new licenses for the same material under section 10.
-
-9. Acceptance Not Required for Having Copies.
-
-You are not required to accept this License in order to receive or run a copy of
-the Program. Ancillary propagation of a covered work occurring solely as a
-consequence of using peer-to-peer transmission to receive a copy likewise does
-not require acceptance. However, nothing other than this License grants you
-permission to propagate or modify any covered work. These actions infringe
-copyright if you do not accept this License. Therefore, by modifying or
-propagating a covered work, you indicate your acceptance of this License to do
-so.
-
-10. Automatic Licensing of Downstream Recipients.
-
-Each time you convey a covered work, the recipient automatically receives a
-license from the original licensors, to run, modify and propagate that work,
-subject to this License. You are not responsible for enforcing compliance by
-third parties with this License.
-
-An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered work results
-from an entity transaction, each party to that transaction who receives a copy
-of the work also receives whatever licenses to the work the party's predecessor
-in interest had or could give under the previous paragraph, plus a right to
-possession of the Corresponding Source of the work from the predecessor in
-interest, if the predecessor has it or can get it with reasonable efforts.
-
-You may not impose any further restrictions on the exercise of the rights
-granted or affirmed under this License. For example, you may not impose a
-license fee, royalty, or other charge for exercise of rights granted under this
-License, and you may not initiate litigation (including a cross-claim or
-counterclaim in a lawsuit) alleging that any patent claim is infringed by
-making, using, selling, offering for sale, or importing the Program or any
-portion of it.
-
-11. Patents.
-
-A "contributor" is a copyright holder who authorizes use under this License of
-the Program or a work on which the Program is based. The work thus licensed is
-called the contributor's "contributor version".
-
-A contributor's "essential patent claims" are all patent claims owned or
-controlled by the contributor, whether already acquired or hereafter acquired,
-that would be infringed by some manner, permitted by this License, of making,
-using, or selling its contributor version, but do not include claims that would
-be infringed only as a consequence of further modification of the contributor
-version. For purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of this License.
-
-Each contributor grants you a non-exclusive, worldwide, royalty-free patent
-license under the contributor's essential patent claims, to make, use, sell,
-offer for sale, import and otherwise run, modify and propagate the contents of
-its contributor version.
-
-In the following three paragraphs, a "patent license" is any express agreement
-or commitment, however denominated, not to enforce a patent (such as an express
-permission to practice a patent or covenant not to sue for patent infringement).
-To "grant" such a patent license to a party means to make such an agreement or
-commitment not to enforce a patent against the party.
-
-If you convey a covered work, knowingly relying on a patent license, and the
-Corresponding Source of the work is not available for anyone to copy, free of
-charge and under the terms of this License, through a publicly available network
-server or other readily accessible means, then you must either (1) cause the
-Corresponding Source to be so available, or (2) arrange to deprive yourself of
-the benefit of the patent license for this particular work, or (3) arrange, in a
-manner consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have actual
-knowledge that, but for the patent license, your conveying the covered work in a
-country, or your recipient's use of the covered work in a country, would
-infringe one or more identifiable patents in that country that you have reason
-to believe are valid.
-
-If, pursuant to or in connection with a single transaction or arrangement, you
-convey, or propagate by procuring conveyance of, a covered work, and grant a
-patent license to some of the parties receiving the covered work authorizing
-them to use, propagate, modify or convey a specific copy of the covered work,
-then the patent license you grant is automatically extended to all recipients of
-the covered work and works based on it.
-
-A patent license is "discriminatory" if it does not include within the scope of
-its coverage, prohibits the exercise of, or is conditioned on the non-exercise
-of one or more of the rights that are specifically granted under this License.
-You may not convey a covered work if you are a party to an arrangement with a
-third party that is in the business of distributing software, under which you
-make payment to the third party based on the extent of your activity of
-conveying the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory patent
-license (a) in connection with copies of the covered work conveyed by you (or
-copies made from those copies), or (b) primarily for and in connection with
-specific products or compilations that contain the covered work, unless you
-entered into that arrangement, or that patent license was granted, prior to 28
-March 2007.
-
-Nothing in this License shall be construed as excluding or limiting any implied
-license or other defenses to infringement that may otherwise be available to you
-under applicable patent law.
-
-12. No Surrender of Others' Freedom.
-
-If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not excuse
-you from the conditions of this License. If you cannot convey a covered work so
-as to satisfy simultaneously your obligations under this License and any other
-pertinent obligations, then as a consequence you may not convey it at all. For
-example, if you agree to terms that obligate you to collect a royalty for
-further conveying from those to whom you convey the Program, the only way you
-could satisfy both those terms and this License would be to refrain entirely
-from conveying the Program.
-
-13. Use with the GNU Affero General Public License.
-
-Notwithstanding any other provision of this License, you have permission to link
-or combine any covered work with a work licensed under version 3 of the GNU
-Affero General Public License into a single combined work, and to convey the
-resulting work. The terms of this License will continue to apply to the part
-which is the covered work, but the special requirements of the GNU Affero
-General Public License, section 13, concerning interaction through a network
-will apply to the combination as such.
-
-14. Revised Versions of this License.
-
-The Free Software Foundation may publish revised and/or new versions of the GNU
-General Public License from time to time. Such new versions will be similar in
-spirit to the present version, but may differ in detail to address new problems
-or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies
-that a certain numbered version of the GNU General Public License "or any later
-version" applies to it, you have the option of following the terms and
-conditions either of that numbered version or of any later version published by
-the Free Software Foundation. If the Program does not specify a version number
-of the GNU General Public License, you may choose any version ever published by
-the Free Software Foundation.
-
-If the Program specifies that a proxy can decide which future versions of the
-GNU General Public License can be used, that proxy's public statement of
-acceptance of a version permanently authorizes you to choose that version for
-the Program.
-
-Later license versions may give you additional or different permissions.
-However, no additional obligations are imposed on any author or copyright holder
-as a result of your choosing to follow a later version.
-
-15. Disclaimer of Warranty.
-
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
-PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
-QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
-DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-16. Limitation of Liability.
-
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
-COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
-PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
-THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
-INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
-HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-17. Interpretation of Sections 15 and 16.
-
-If the disclaimer of warranty and limitation of liability provided above cannot
-be given local legal effect according to their terms, reviewing courts shall
-apply local law that most closely approximates an absolute waiver of all civil
-liability in connection with the Program, unless a warranty or assumption of
-liability accompanies a copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest possible use
-to the public, the best way to achieve this is to make it free software which
-everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to attach
-them to the start of each source file to most effectively state the exclusion of
-warranty; and each file should have at least the "copyright" line and a pointer
-to where the full notice is found.
-
- Triplex — The React Three Fiber editor
- Copyright (C) 2022-Present Michael Dougall
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program does terminal interaction, make it output a short notice like
-this when it starts in an interactive mode:
-
- Triplex Copyright (C) 2022-Present Michael Dougall
- This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands might be
-different; for a GUI interface, you would use an "about box".
-
-You should also get your employer (if you work as a programmer) or school, if
-any, to sign a "copyright disclaimer" for the program, if necessary. For more
-information on this, and how to apply and follow the GNU GPL, see
-.
-
-The GNU General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may consider
-it more useful to permit linking proprietary applications with the library. If
-this is what you want to do, use the GNU Lesser General Public License instead
-of this License. But first, please read
-.
diff --git a/packages/editor/README.md b/packages/editor/README.md
deleted file mode 100644
index ae52548e..00000000
--- a/packages/editor/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# @triplex/editor
diff --git a/packages/editor/index.html b/packages/editor/index.html
deleted file mode 100644
index 57b40f0b..00000000
--- a/packages/editor/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
- Triplex
-
-
-
-
-
-
diff --git a/packages/editor/package.json b/packages/editor/package.json
deleted file mode 100644
index de0677c8..00000000
--- a/packages/editor/package.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- "name": "@triplex/editor",
- "version": "0.58.2",
- "private": true,
- "description": "The React Three Fiber editor.",
- "license": "GPL-3.0",
- "author": "Michael Dougall (https://twitter.com/itsdouges)",
- "main": "./src/main-dev-only.ts",
- "types": "./src/main-dev-only.ts",
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "vite build",
- "typedef": "tsc"
- },
- "dependencies": {
- "@radix-ui/react-dialog": "^1.0.3",
- "@radix-ui/react-icons": "^1.3.0",
- "@radix-ui/react-menubar": "^1.0.2",
- "@radix-ui/react-scroll-area": "^1.0.3",
- "@triplex/bridge": "0.58.2",
- "@triplex/ws-client": "0.58.2",
- "react-dom": "^18.2.0",
- "react-error-boundary": "^3.1.4",
- "react-router-dom": "^6.7.0",
- "suspend-react": "^0.0.9",
- "tinycolor2": "^1.6.0",
- "zustand": "^4.3.2"
- },
- "devDependencies": {
- "@swc/cli": "^0.1.59",
- "@swc/core": "^1.3.28",
- "@testing-library/react": "^14.0.0",
- "@triplex/server": "^0.58.2",
- "@types/react": "^18.0.27",
- "@types/react-dom": "^18.0.10",
- "@types/three": "^0.157.0",
- "@types/tinycolor2": "^1.4.3",
- "@vitejs/plugin-react": "^3.0.1",
- "tailwindcss": "^3.3.2",
- "three": "^0.157.0",
- "typescript": "^4.9.4",
- "vite": "^4.4.11"
- },
- "peerDependencies": {
- "@react-three/fiber": "^8.0.0",
- "react": "^18.0.0",
- "three": ">=0.153.0"
- }
-}
diff --git a/packages/editor/postcss.config.js b/packages/editor/postcss.config.js
deleted file mode 100644
index 4ea687d6..00000000
--- a/packages/editor/postcss.config.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-module.exports = {
- plugins: {
- autoprefixer: {},
- tailwindcss: {},
- },
-};
diff --git a/packages/editor/public/banner-r3f.jpg b/packages/editor/public/banner-r3f.jpg
deleted file mode 100644
index f2543a56..00000000
Binary files a/packages/editor/public/banner-r3f.jpg and /dev/null differ
diff --git a/packages/editor/src/ds/README.md b/packages/editor/src/ds/README.md
deleted file mode 100644
index b506641d..00000000
--- a/packages/editor/src/ds/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-This is where any pieces of UI will go that can be considered an atom, such as a
-button. For components that form an experience (such as a scene menu) put them
-in the ui folder.
diff --git a/packages/editor/src/ds/button.tsx b/packages/editor/src/ds/button.tsx
deleted file mode 100644
index 6bafccfa..00000000
--- a/packages/editor/src/ds/button.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { IconProps } from "@radix-ui/react-icons/dist/types";
-import { ComponentType, forwardRef } from "react";
-import { cn } from "./cn";
-
-export const IconButton = forwardRef<
- HTMLButtonElement,
- {
- className?: string;
- icon: ComponentType;
- isDisabled?: boolean;
- isSelected?: boolean | "partial";
- onClick?: () => void;
- size?: "default" | "tight";
- testId?: string;
- title: string;
- variant?: "default" | "inverse";
- }
->(
- (
- {
- className,
- icon: Icon,
- isDisabled,
- isSelected,
- onClick,
- size = "default",
- testId,
- title,
- variant = "default",
- },
- ref
- ) => (
-
- )
-);
-
-IconButton.displayName = "IconButton";
-
-export const Button = forwardRef<
- HTMLButtonElement,
- {
- children: string;
- className?: string;
- disabled?: boolean;
- icon?: ComponentType;
- isSelected?: boolean;
- onClick?: () => void;
- size?: "default" | "tight";
- testId?: string;
- variant?: "default" | "inverse";
- }
->(
- (
- {
- children,
- className,
- disabled,
- icon: Icon,
- isSelected,
- onClick,
- size = "default",
- testId,
- variant = "default",
- },
- ref
- ) => (
-
- )
-);
-
-Button.displayName = "Button";
diff --git a/packages/editor/src/ds/cn.ts b/packages/editor/src/ds/cn.ts
deleted file mode 100644
index c6822a40..00000000
--- a/packages/editor/src/ds/cn.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-type ClassNames = string | false | undefined | ClassNames[];
-
-function collectDecls(
- classNames: ClassNames[],
- outDecls: Record
-): void {
- for (let i = 0; i < classNames.length; i++) {
- const className = classNames[i];
-
- if (Array.isArray(className)) {
- collectDecls(className, outDecls);
- } else if (className) {
- const parts = className.split(" ");
-
- for (let x = 0; x < parts.length; x++) {
- const part = parts[x];
- outDecls[part] = part;
- }
- }
- }
-}
-
-export function cn(classNames: ClassNames[]): string | undefined {
- const decls: Record = {};
-
- collectDecls(classNames, decls);
-
- const str = [];
-
- for (const key in decls) {
- const value = decls[key];
- str.push(value);
- }
-
- return str.join(" ");
-}
diff --git a/packages/editor/src/ds/drawer.tsx b/packages/editor/src/ds/drawer.tsx
deleted file mode 100644
index db1f837d..00000000
--- a/packages/editor/src/ds/drawer.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-// eslint-disable-next-line import/no-namespace
-import * as Dialog from "@radix-ui/react-dialog";
-import { cn } from "./cn";
-
-export function Drawer({
- attach = "left",
- children,
- mode = "blocking",
- onClose,
- open,
- title,
-}: {
- attach?: "left" | "bottom";
- children: React.ReactNode;
- mode?: "blocking" | "transparent";
- onClose: () => void;
- open: boolean;
- title: string;
-}) {
- return (
- !isOpen && onClose()} open={open}>
-
-
-
- {title}
- {children}
-
-
-
- );
-}
diff --git a/packages/editor/src/ds/menubar.tsx b/packages/editor/src/ds/menubar.tsx
deleted file mode 100644
index 90c8fec1..00000000
--- a/packages/editor/src/ds/menubar.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-// eslint-disable-next-line import/no-namespace
-import * as RadixMenubar from "@radix-ui/react-menubar";
-import { ReactNode } from "react";
-import { cn } from "./cn";
-
-export function Trigger({
- children,
- ...props
-}: RadixMenubar.MenubarTriggerProps) {
- return (
-
- {children}
-
- );
-}
-
-export function MenuContent({
- children,
- ...props
-}: RadixMenubar.MenuContentProps) {
- return (
-
-
- {children}
-
-
- );
-}
-
-export function MenuItem({
- children,
- disabled,
- onClick,
- rslot,
- ...props
-}: RadixMenubar.MenuItemProps & { rslot?: ReactNode }) {
- return (
-
- {children}
- {rslot &&
{rslot}
}
-
- );
-}
-
-export function Menu({ children }: RadixMenubar.MenubarMenuProps) {
- return {children};
-}
-
-export function Menubar({ children }: RadixMenubar.MenubarProps) {
- return {children};
-}
-
-export function Separator() {
- return (
-
- );
-}
diff --git a/packages/editor/src/ds/pressable.tsx b/packages/editor/src/ds/pressable.tsx
deleted file mode 100644
index d8a24cab..00000000
--- a/packages/editor/src/ds/pressable.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import {
- forwardRef,
- KeyboardEventHandler,
- MouseEventHandler,
- useCallback,
-} from "react";
-import { cn } from "./cn";
-
-export const Pressable = forwardRef<
- HTMLDivElement,
- {
- children?: React.ReactNode;
- className?: string;
- onPress?: () => void;
- style?: React.CSSProperties;
- title?: string;
- }
->(({ children, className, onPress, style, title }, ref) => {
- const onKeyDownHandler: KeyboardEventHandler = useCallback(
- (e) => {
- if (e.key === "Enter") {
- onPress?.();
- e.stopPropagation();
- }
- },
- [onPress]
- );
-
- const onKeyUpHandler: KeyboardEventHandler = useCallback(
- (e) => {
- if (e.key === " ") {
- onPress?.();
- e.stopPropagation();
- }
- },
- [onPress]
- );
-
- const onClickHandler: MouseEventHandler = useCallback(
- (e) => {
- onPress?.();
- e.stopPropagation();
- },
- [onPress]
- );
-
- return (
-
- {children}
-
- );
-});
-
-Pressable.displayName = "Pressable";
diff --git a/packages/editor/src/ds/scroll-container.tsx b/packages/editor/src/ds/scroll-container.tsx
deleted file mode 100644
index 1b98dd0e..00000000
--- a/packages/editor/src/ds/scroll-container.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import {
- Corner,
- Root,
- Scrollbar,
- Thumb,
- Viewport,
-} from "@radix-ui/react-scroll-area";
-import { cn } from "./cn";
-
-export function ScrollContainer({
- children,
- className,
-}: {
- children: React.ReactNode;
- className?: string;
-}) {
- return (
-
- {children}
-
-
-
-
-
- );
-}
diff --git a/packages/editor/src/editor.tsx b/packages/editor/src/editor.tsx
deleted file mode 100644
index 10b4a489..00000000
--- a/packages/editor/src/editor.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { SceneFrame } from "./scence-bridge";
-import { useEditor } from "./stores/editor";
-import { AssetsDrawer } from "./ui/assets-drawer";
-import { ContextPanel } from "./ui/context-panel";
-import { ControlsMenu } from "./ui/controls-menu";
-import { ProviderConfig } from "./ui/provider-config";
-import { ScenePanel } from "./ui/scene-panel";
-import { ScenesDrawer } from "./ui/scenes-drawer";
-
-export function EditorFrame() {
- const { path } = useEditor();
-
- return (
- <>
-
-
-
- {path && }
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
-}
diff --git a/packages/editor/src/environment.tsx b/packages/editor/src/environment.tsx
deleted file mode 100644
index 2b3fb0be..00000000
--- a/packages/editor/src/environment.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { createContext, ReactNode, useContext } from "react";
-import { suspend } from "suspend-react";
-
-type Env = Awaited>;
-
-const Context = createContext(null);
-
-export function useEnvironment() {
- const context = useContext(Context);
- if (!context) {
- throw new Error("invariant");
- }
-
- return context;
-}
-
-export function Environment({ children }: { children: ReactNode }) {
- const data: Env = suspend(
- () =>
- __TRIPLEX_TARGET__ === "electron"
- ? window.triplex.getEnv()
- : Promise.resolve({
- config: { provider: "", sceneUrl: "", serverUrl: "", wsUrl: "" },
- }),
- []
- );
-
- return {children};
-}
diff --git a/packages/editor/src/index.tsx b/packages/editor/src/index.tsx
deleted file mode 100644
index f10659dd..00000000
--- a/packages/editor/src/index.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { createRoot } from "react-dom/client";
-import { BrowserRouter } from "react-router-dom";
-import { cn } from "./ds/cn";
-import { EditorFrame } from "./editor";
-import { ErrorOverlay } from "./ui/error-overlay";
-import { TitleBar } from "./ui/title-bar";
-import "./styles.css";
-import { Suspense } from "react";
-import { Environment } from "./environment";
-
-createRoot(document.getElementById("root")!).render(
-
-
-
-
-
-
-
-
-
-
-
-);
diff --git a/packages/editor/src/main-dev-only.ts b/packages/editor/src/main-dev-only.ts
deleted file mode 100644
index 1b1a8b08..00000000
--- a/packages/editor/src/main-dev-only.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { join } from "node:path";
-
-export async function createDevServer(): Promise<{
- listen: (port: number) => Promise;
-}> {
- const { createServer: createViteServer } = await import("vite");
-
- const vite = await createViteServer({
- clearScreen: false,
- css: {
- postcss: {
- plugins: [
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- ((await import("tailwindcss")).default as any)(
- (
- await import(
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error
- "../tailwind.config.js"
- )
- ).default
- ),
- ],
- },
- },
- root: join(__dirname, "../"),
- });
-
- return {
- listen: async (port) => {
- const server = await vite.listen(port);
-
- const close = async () => {
- try {
- await server.close();
- await vite.close();
- } finally {
- process.exit(0);
- }
- };
-
- process.once("SIGINT", close);
- process.once("SIGTERM", close);
- },
- };
-}
diff --git a/packages/editor/src/scence-bridge.tsx b/packages/editor/src/scence-bridge.tsx
deleted file mode 100644
index 2f13ee53..00000000
--- a/packages/editor/src/scence-bridge.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { compose, listen } from "@triplex/bridge/host";
-import { useEffect, useState } from "react";
-import { useEnvironment } from "./environment";
-import { useEditor } from "./stores/editor";
-import { useScene } from "./stores/scene";
-import { useUndoRedoState } from "./stores/undo-redo";
-
-export interface FocusedObject {
- column: number;
- line: number;
- path: string;
-}
-
-export function SceneFrame() {
- const editor = useEditor();
- const [initialPath] = useState(() => editor.path);
- const [initialProps] = useState(() => editor.encodedProps);
- const [initialExportName] = useState(() => editor.exportName);
- const sceneReady = useScene((prev) => prev.sceneReady);
- const env = useEnvironment();
-
- useEffect(() => {
- return listen("trplx:onConnected", sceneReady);
- }, [sceneReady]);
-
- return (
- <>
-
-
-
- >
- );
-}
-
-function BridgeSendEvents() {
- const scene = useScene();
- const editor = useEditor();
-
- useEffect(() => {
- if (!scene.ready) {
- return;
- }
-
- // This handles the browser history being updated and propagating to the scene.
- scene.navigateTo({
- encodedProps: editor.encodedProps,
- exportName: editor.exportName,
- path: editor.path,
- });
- }, [editor.encodedProps, editor.exportName, editor.path, scene]);
-
- return null;
-}
-
-function BridgeReceiveEvents() {
- const editor = useEditor();
- const scene = useScene();
- const undo = useUndoRedoState((store) => store.undo);
- const redo = useUndoRedoState((store) => store.redo);
-
- useEffect(() => {
- if (!scene.ready) {
- return;
- }
-
- return compose([
- listen("trplx:onAddNewComponent", editor.addComponent),
- listen("trplx:requestDeleteSceneObject", editor.deleteComponent),
- listen("trplx:requestSave", editor.save),
- listen("trplx:requestUndo", undo),
- listen("trplx:requestRedo", redo),
- listen("trplx:onSceneObjectNavigated", (data) => {
- editor.set(
- {
- encodedProps: data.encodedProps,
- exportName: data.exportName,
- path: data.path,
- },
- data.entered ? { entered: true } : undefined
- );
- }),
- listen("trplx:onConfirmSceneObjectProp", async (data) => {
- const currentPropValue = await scene.getPropValue(data);
-
- editor.persistPropValue({
- column: data.column,
- currentPropValue: currentPropValue.value,
- line: data.line,
- nextPropValue: data.propValue,
- path: data.path,
- propName: data.propName,
- });
- }),
- listen("trplx:onSceneObjectFocus", (data) => {
- editor.focus(data);
- }),
- listen("trplx:onSceneObjectBlur", () => {
- editor.focus(null);
- }),
- ]);
- }, [scene, editor, undo, redo]);
-
- return null;
-}
diff --git a/packages/editor/src/stores/README.md b/packages/editor/src/stores/README.md
deleted file mode 100644
index bfed4de4..00000000
--- a/packages/editor/src/stores/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-This folder should house shared state (both local and remote) for use across the
-editor app.
diff --git a/packages/editor/src/stores/assets-drawer.tsx b/packages/editor/src/stores/assets-drawer.tsx
deleted file mode 100644
index bd69d911..00000000
--- a/packages/editor/src/stores/assets-drawer.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { create } from "zustand";
-
-interface AssetsDrawer {
- hide: () => void;
- show: (target?: {
- column: number;
- exportName: string;
- line: number;
- path: string;
- }) => void;
- shown:
- | boolean
- | { column: number; exportName: string; line: number; path: string };
-}
-
-export const useAssetsDrawer = create((set) => ({
- hide: () => set({ shown: false }),
- show: (object) => set({ shown: object || true }),
- shown: false,
-}));
diff --git a/packages/editor/src/stores/editor.tsx b/packages/editor/src/stores/editor.tsx
deleted file mode 100644
index 0769bf7f..00000000
--- a/packages/editor/src/stores/editor.tsx
+++ /dev/null
@@ -1,452 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import type { ComponentTarget, ComponentType } from "@triplex/server";
-import { useCallback, useMemo } from "react";
-import { useSearchParams } from "react-router-dom";
-import { create } from "zustand";
-import { showSaveDialog } from "../util/prompt";
-import { stringifyJSON } from "../util/string";
-import { useScene } from "./scene";
-import { useUndoRedoState } from "./undo-redo";
-
-export interface Params {
- encodedProps: string;
- exportName: string;
- path: string;
-}
-
-export interface FocusedObject {
- column: number;
- line: number;
- parentPath: string;
- path: string;
-}
-
-interface SelectionState {
- focus: (obj: FocusedObject | null) => void;
- focused: FocusedObject | null;
-}
-
-interface PersistPropValue {
- column: number;
- currentPropValue: unknown;
- line: number;
- nextPropValue: unknown;
- path: string;
- propName: string;
-}
-
-const useSelectionStore = create((set) => ({
- focus: (sceneObject) => set({ focused: sceneObject }),
- focused: null,
-}));
-
-/**
- * **useEditor()**
- *
- * Exposes controls for the editor, calls out to the scene store when needing to
- * mutate the currently open scene.
- *
- * @see {@link ./scene.tsx}
- */
-export function useEditor() {
- const [searchParams, setSearchParams] = useSearchParams({ path: "" });
- const path = searchParams.get("path") || "";
- const encodedProps = searchParams.get("props") || "";
- const exportName = searchParams.get("exportName") || "";
- const enteredComponent = !!searchParams.get("entered") || false;
- const focus = useSelectionStore((store) => store.focus);
- const target = useSelectionStore((store) => store.focused);
- const scene = useScene();
- const performUndoableEvent = useUndoRedoState(
- (store) => store.performUndoableEvent
- );
- const clearUndoRedo = useUndoRedoState((store) => store.clearUndoRedo);
-
- const addComponent = useCallback(
- async ({
- target,
- type,
- }: {
- target?: ComponentTarget;
- type: ComponentType;
- }) => {
- const componentPath = target ? target.path : path;
- const componentExportName = target ? target.exportName : exportName;
-
- const res = await fetch(
- "http://localhost:8000/scene/" +
- encodeURIComponent(componentPath) +
- `/${componentExportName}/object`,
- {
- body: JSON.stringify({
- target,
- type,
- }),
- method: "POST",
- }
- );
-
- const result = (await res.json()) as {
- column: number;
- line: number;
- path: string;
- };
-
- scene.focus({
- column: result.column,
- line: result.line,
- parentPath: componentPath,
- path: componentPath,
- });
-
- return result;
- },
- [path, exportName, scene]
- );
-
- const deleteComponent = useCallback(() => {
- if (!target) {
- return;
- }
-
- const undoAction = () => {
- fetch(
- `http://localhost:8000/scene/${encodeURIComponent(path)}/object/${
- target.line
- }/${target.column}/restore`,
- { method: "POST" }
- );
- scene.restoreComponent({
- column: target.column,
- line: target.line,
- parentPath: target.parentPath,
- });
- };
-
- const redoAction = () => {
- fetch(
- `http://localhost:8000/scene/${encodeURIComponent(path)}/object/${
- target.line
- }/${target.column}/delete`,
- { method: "POST" }
- );
- scene.deleteComponent({
- column: target.column,
- line: target.line,
- parentPath: target.parentPath,
- });
- };
-
- performUndoableEvent({
- redo: redoAction,
- undo: undoAction,
- });
-
- scene.blur();
- }, [path, performUndoableEvent, scene, target]);
-
- const exitComponent = useCallback(() => {
- window.history.back();
- }, []);
-
- const persistPropValue = useCallback(
- (data: PersistPropValue) => {
- const undoAction = () => {
- const propData = {
- column: data.column,
- line: data.line,
- path: data.path,
- propName: data.propName,
- propValue: data.currentPropValue,
- };
-
- scene.setPropValue(propData);
- scene.persistPropValue(propData);
-
- fetch(
- `http://localhost:8000/scene/object/${data.line}/${
- data.column
- }/prop?value=${encodeURIComponent(
- stringifyJSON(data.currentPropValue)
- )}&path=${encodeURIComponent(data.path)}&name=${encodeURIComponent(
- data.propName
- )}`
- );
- };
-
- const redoAction = () => {
- const propData = {
- column: data.column,
- line: data.line,
- path: data.path,
- propName: data.propName,
- propValue: data.nextPropValue,
- };
-
- scene.setPropValue(propData);
- scene.persistPropValue(propData);
-
- fetch(
- `http://localhost:8000/scene/object/${data.line}/${
- data.column
- }/prop?value=${encodeURIComponent(
- stringifyJSON(data.nextPropValue)
- )}&path=${encodeURIComponent(data.path)}&name=${encodeURIComponent(
- data.propName
- )}`
- );
- };
-
- performUndoableEvent({
- redo: redoAction,
- undo: undoAction,
- });
- },
- [performUndoableEvent, scene]
- );
-
- const reset = useCallback(() => {
- clearUndoRedo();
-
- scene.blur();
- scene.reset();
-
- fetch(`http://localhost:8000/scene/${encodeURIComponent(path)}/reset`);
- }, [clearUndoRedo, path, scene]);
-
- if (path && !exportName) {
- throw new Error("invariant: exportName is undefined");
- }
-
- const set = useCallback(
- (
- componentParams: Params,
- metaParams: {
- entered?: true;
- forceSaveAs?: true;
- replace?: true;
- } = {}
- ) => {
- if (
- componentParams.path === path &&
- componentParams.exportName === exportName &&
- metaParams.forceSaveAs === undefined &&
- metaParams.replace === undefined
- ) {
- // Bail if we're already on the same path.
- // If we implement props being able to change
- // We'll need to do more work here later.
- return;
- }
-
- const newParams: Record = {};
-
- if (componentParams.path) {
- newParams.path = componentParams.path;
- }
-
- if (componentParams.encodedProps) {
- newParams.props = componentParams.encodedProps;
- }
-
- if (componentParams.exportName) {
- newParams.exportName = componentParams.exportName;
- }
-
- if (metaParams.entered) {
- newParams.entered = "true";
- }
-
- if (metaParams.forceSaveAs) {
- newParams.forceSaveAs = "true";
- }
-
- setSearchParams(newParams, { replace: metaParams.replace });
- },
- [exportName, path, setSearchParams]
- );
-
- const save = useCallback(
- async (saveAs = !!searchParams.get("forceSaveAs")) => {
- let actualPath = path;
-
- if (saveAs) {
- const enteredPath = await showSaveDialog(path);
- if (!enteredPath) {
- // Abort, user cleared filename or cancelled.
- return;
- } else {
- actualPath = enteredPath;
- }
- }
-
- // Clear the update stack as the line and column numbers of jsx elements
- // Will most likely change after formatting resulting in the rpc calls not
- // Working anymore.
- clearUndoRedo();
-
- await fetch("http://localhost:8000/project/save", {
- body: JSON.stringify({
- rename: path !== actualPath ? { [path]: actualPath } : {},
- }),
- method: "POST",
- });
-
- if (actualPath !== path) {
- // The path has changed so we need to update the URL to reflect that.
- set(
- {
- encodedProps,
- exportName,
- path: actualPath,
- },
- { replace: true }
- );
- }
- },
- [clearUndoRedo, encodedProps, exportName, path, searchParams, set]
- );
-
- const newFile = useCallback(async () => {
- const result = await fetch(`http://localhost:8000/scene/new`, {
- method: "POST",
- });
- const data = await result.json();
-
- set(
- {
- encodedProps: "",
- exportName: data.exportName,
- path: data.path,
- },
- { forceSaveAs: true }
- );
- }, [set]);
-
- const newComponent = useCallback(async () => {
- const result = await fetch(
- `http://localhost:8000/scene/${encodeURIComponent(path)}/new`,
- { method: "POST" }
- );
- const data = await result.json();
-
- set({
- encodedProps: "",
- exportName: data.exportName,
- path: data.path,
- });
- }, [path, set]);
-
- return useMemo(
- () => ({
- /**
- * Adds the component into the current file. Is not persisted until `save()` is
- * called.
- */
- addComponent,
-
- /**
- * Deletes the currently focused scene object. Able to be undone. Is not
- * persisted until `save()` is called.
- */
- deleteComponent,
-
- /**
- * Encoded (via `encodeURIComponent()`) props used to hydrate the loaded scene.
- */
- encodedProps,
-
- /**
- * Will be `true` when entered a component via a owning parent, else `false`.
- * Enter a component via `scene.navigateTo()`.
- *
- * @see {@link ./scene.tsx}
- */
- enteredComponent,
-
- /**
- * Exits the currently entered component and goes back to the parent.
- */
- exitComponent,
-
- /**
- * Returns the scene export name that is currently open.
- */
- exportName,
-
- /**
- * Focuses the passed scene object. Will blur the currently focused scene object
- * by passing `null`.
- *
- * You should probably be calling the scene API instead.
- *
- * @see {@link ./scene.tsx}
- */
- focus,
-
- /**
- * Creates a new intermediate component in the open file and transitions the
- * editor to it.
- */
- newComponent,
-
- /**
- * Creates a new intermediate file and transitions the editor to the file.
- */
- newFile,
-
- /**
- * Current value of the scene path.
- */
- path,
-
- /**
- * Persists the passed in prop value to the scene frame and web server, and
- * makes it available as an undo/redo action.
- */
- persistPropValue,
-
- /**
- * Resets the scene throwing away any unsaved state.
- */
- reset,
-
- /**
- * Calls the web server to save the intermediate scene source to file system.
- */
- save,
-
- /**
- * Sets the loaded scene to a specific path, export name, and props.
- */
- set,
-
- /**
- * Returns the currently focused scene object, else `null`.
- */
- target,
- }),
- [
- addComponent,
- deleteComponent,
- encodedProps,
- enteredComponent,
- exitComponent,
- exportName,
- focus,
- newComponent,
- newFile,
- path,
- persistPropValue,
- reset,
- save,
- set,
- target,
- ]
- );
-}
diff --git a/packages/editor/src/stores/overlay.tsx b/packages/editor/src/stores/overlay.tsx
deleted file mode 100644
index 05482ef9..00000000
--- a/packages/editor/src/stores/overlay.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { create } from "zustand";
-
-interface OverlayState {
- show: (shown: false | "open-scene") => void;
- shown: false | "open-scene";
-}
-
-export const useOverlayStore = create((set) => ({
- show: (shown) => set({ shown }),
- shown: false,
-}));
diff --git a/packages/editor/src/stores/provider.tsx b/packages/editor/src/stores/provider.tsx
deleted file mode 100644
index 2bba3f3c..00000000
--- a/packages/editor/src/stores/provider.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { create } from "zustand";
-
-export const useProviderStore = create<{
- hide: () => void;
- show: () => void;
- shown: boolean;
- toggle: () => void;
-}>((set, get) => ({
- hide: () => set({ shown: false }),
- show: () => set({ shown: true }),
- shown: false,
- toggle: () => set({ shown: !get().shown }),
-}));
diff --git a/packages/editor/src/stores/scene-state.tsx b/packages/editor/src/stores/scene-state.tsx
deleted file mode 100644
index 20646cc7..00000000
--- a/packages/editor/src/stores/scene-state.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { create } from "zustand";
-
-interface SceneState {
- __internalState: Record>;
- clear(key: string): void;
- get(key: string): Record;
- hasState(key: string): boolean;
- set(key: string, name: string, value: unknown): void;
-}
-
-export const useSceneState = create((setStore, get) => ({
- __internalState: {},
- clear(key) {
- const current = get();
- setStore({
- __internalState: {
- ...current.__internalState,
- [key]: {},
- },
- });
- },
- get(key) {
- const current = get();
- return current.__internalState[key] || {};
- },
- hasState(key) {
- const current = get();
- return Object.keys(current.__internalState[key] || {}).length > 0;
- },
- set(key, name, value) {
- const current = get();
- const nextValue = {
- __internalState: {
- ...current.__internalState,
- [key]: {
- ...current.__internalState[key],
- [name]: value,
- },
- },
- };
-
- if (value === undefined) {
- delete nextValue.__internalState[key][name];
- }
-
- setStore(nextValue);
- },
-}));
diff --git a/packages/editor/src/stores/scene.tsx b/packages/editor/src/stores/scene.tsx
deleted file mode 100644
index c5eeee45..00000000
--- a/packages/editor/src/stores/scene.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { send } from "@triplex/bridge/host";
-import type { ComponentTarget, ComponentType } from "@triplex/server";
-import { create } from "zustand";
-
-export interface FocusedObject {
- column: number;
- line: number;
- parentPath: string;
- path: string;
-}
-
-interface BridgeContext {
- /**
- * Adds a component to the scene until any HMR event is fired whereby all
- * added components are removed.
- */
- addComponent(data: { target?: ComponentTarget; type: ComponentType }): void;
- /**
- * Removes focus from the currently selected scene object.
- */
- blur(): void;
- /**
- * Deletes a component from the scene. Will try to persist state if possible.
- */
- deleteComponent(component: {
- column: number;
- line: number;
- parentPath: string;
- }): void;
- /**
- * Focuses the passed in scene object. This will open the context panel and
- * enable some editor capabilities for the selected scene object.
- */
- focus(sceneObject: FocusedObject): void;
- /**
- * Returns the persisted prop value. It should not return the current
- * intermediate value.
- */
- getPropValue(prop: {
- column: number;
- line: number;
- path: string;
- propName: string;
- }): Promise<{ value: unknown }>;
- /**
- * Jumps the scene camera to the currently focused scene object.
- */
- jumpTo(): void;
- /**
- * Navigate the scene to the scene object.
- *
- * @param sceneObject Navigates to the passed in scene object. When undefined
- * navigates to the currently focused scene object.
- */
- navigateTo(sceneObject?: {
- encodedProps: string;
- exportName: string;
- path: string;
- }): void;
- /**
- * Persists the value of a prop which tells the editor that this is now the
- * current value of the prop. This should only be called after a change has
- * been "completed", for example during a mouse up event or blur event.
- */
- persistPropValue(prop: {
- column: number;
- line: number;
- path: string;
- propName: string;
- propValue: unknown;
- }): void;
- /**
- * Value is `true` when the scene is ready else `false`. If the scene is not
- * ready accessing any of the scene store values will throw an invariant.
- */
- ready: boolean;
- /**
- * Refreshes the scene.
- */
- refresh(opts?: { hard?: boolean }): void;
- /**
- * Clears out the scene of any intermediate state. Generally you'll want to
- * use the editor store instead of this one directly.
- *
- * @see {@link ./editor.tsx}
- */
- reset(): void;
- /**
- * Resets the triplex camera back to the editor default.
- */
- resetCamera(): void;
- /**
- * Restores a component that was previously deleted from the scene.
- */
- restoreComponent(component: {
- column: number;
- line: number;
- parentPath: string;
- }): void;
- /**
- * Sets the scene camera type.
- */
- setCameraType(type: "perspective" | "orthographic"): void;
- /**
- * Sets the value of a prop in the scene frame. This can be set as frequently
- * as needed as is considered the intermediate values during a change. When
- * setting a prop value it is not yet considered "persisted".
- */
- setPropValue(prop: {
- column: number;
- line: number;
- path: string;
- propName: string;
- propValue: unknown;
- }): void;
- /**
- * Sets the scene transform control mode.
- */
- setTransform(mode: "scale" | "translate" | "rotate"): void;
- /**
- * Switches the triplex camera to the currently focused camera. If the focused
- * scene object is not a camera is noops.
- */
- viewFocusedCamera(): void;
-}
-
-/**
- * **useScene()**
- *
- * Allows you to imperatively control the scene opened by the editor. Generally
- * you'll want to use the editor store instead of this one.
- *
- * @see {@link ./editor.tsx}
- */
-export const useScene = create void }>(
- (setStore) => ({
- addComponent(data) {
- send("trplx:requestAddNewComponent", data);
- },
- blur() {
- send("trplx:requestBlurSceneObject", undefined);
- },
- deleteComponent(data) {
- send("trplx:requestDeleteSceneObject", data);
- },
- focus(sceneObject) {
- send("trplx:requestFocusSceneObject", sceneObject);
- },
- getPropValue(prop) {
- return send("trplx:requestSceneObjectPropValue", prop, true);
- },
- jumpTo() {
- send("trplx:requestJumpToSceneObject", undefined);
- },
- navigateTo(sceneObject) {
- send("trplx:requestNavigateToScene", sceneObject);
- },
- persistPropValue(data) {
- send("trplx:requestPersistSceneObjectProp", data);
- },
- ready: false,
- refresh({ hard }: { hard?: boolean } = {}) {
- send("trplx:requestRefresh", { hard });
- },
- reset() {
- send("trplx:requestReset", undefined);
- },
- resetCamera() {
- send("trplx:requestAction", { action: "resetCamera" });
- },
- restoreComponent(data) {
- send("trplx:requestRestoreSceneObject", data);
- },
- sceneReady() {
- setStore({ ready: true });
- },
- setCameraType(type) {
- send("trplx:requestCameraTypeChange", { type });
- },
- setPropValue(data) {
- send("trplx:requestSetSceneObjectProp", data);
- },
- setTransform(mode) {
- send("trplx:requestTransformChange", { mode });
- },
- viewFocusedCamera() {
- send("trplx:requestAction", { action: "viewFocusedCamera" });
- },
- })
-);
diff --git a/packages/editor/src/stores/undo-redo.tsx b/packages/editor/src/stores/undo-redo.tsx
deleted file mode 100644
index bdbc7b71..00000000
--- a/packages/editor/src/stores/undo-redo.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { create } from "zustand";
-
-interface UndoableEvent {
- redo: () => void;
- undo: () => void;
-}
-
-interface UndoRedoState {
- clearUndoRedo(): void;
- performUndoableEvent(event: UndoableEvent): void;
- redo(): void;
- redoAvailable: boolean;
- stack: { redo: UndoableEvent[]; undo: UndoableEvent[] };
- undo(): void;
- undoAvailable: boolean;
-}
-
-export const useUndoRedoState = create((set, getState) => ({
- clearUndoRedo() {
- set({
- redoAvailable: false,
- stack: { redo: [], undo: [] },
- undoAvailable: false,
- });
- },
- performUndoableEvent(event) {
- const state = getState();
- state.stack.undo.push(event);
- state.stack.redo.length = 0;
- event.redo();
-
- set({
- redoAvailable: false,
- undoAvailable: true,
- });
- },
- redo() {
- const state = getState();
- const action = state.stack.redo.pop();
-
- if (action) {
- action.redo();
- state.stack.undo.push(action);
-
- set({
- redoAvailable: state.stack.redo.length > 0,
- undoAvailable: state.stack.undo.length > 0,
- });
- }
- },
- redoAvailable: false,
- stack: { redo: [], undo: [] },
- undo() {
- const state = getState();
- const action = state.stack.undo.pop();
-
- if (action) {
- action.undo();
- state.stack.redo.push(action);
-
- set({
- redoAvailable: state.stack.redo.length > 0,
- undoAvailable: state.stack.undo.length > 0,
- });
- }
- },
- undoAvailable: false,
-}));
diff --git a/packages/editor/src/styles.css b/packages/editor/src/styles.css
deleted file mode 100644
index e84af0cc..00000000
--- a/packages/editor/src/styles.css
+++ /dev/null
@@ -1,125 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-@keyframes slide-in {
- from {
- transform: translateX(-100%);
- }
-
- to {
- transform: translateX(0%);
- }
-}
-
-@keyframes slide-up {
- from {
- transform: translateY(100%);
- }
-
- to {
- transform: translateY(0%);
- }
-}
-
-@keyframes fade-in {
- from {
- opacity: 0;
- transform: translateY(8px);
- }
-
- to {
- opacity: 1;
- transform: translateY(0);
- }
-}
-
-@keyframes border-danger-flash {
- from {
- border-color: rgb(248 113 113);
- }
-}
-
-.highlight-danger {
- animation-name: border-danger-flash;
- animation-duration: 10000ms;
-}
-
-.fade-in {
- animation-name: fade-in;
- animation-duration: 100ms;
-}
-
-.slide-in {
- animation-name: slide-in;
- animation-duration: 100ms;
-}
-
-.slide-up {
- animation-name: slide-up;
- animation-duration: 100ms;
-}
-
-input[type="color"]::-moz-color-swatch {
- border: none;
- border-radius: 3px;
-}
-
-input[type="color"]::-webkit-color-swatch-wrapper {
- padding: 0;
- border-radius: 0;
-}
-
-input[type="color"]::-webkit-color-swatch {
- border: none;
-}
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
- appearance: none;
-}
-
-html {
- -moz-osx-font-smoothing: grayscale;
- font-feature-settings: "rlig" 1, "calt" 1, "ss01" 1;
-}
-
-.bg-checker {
- background-position: 0px 0px, 10px 10px;
- background-size: 20px 20px;
- background-image: linear-gradient(
- 45deg,
- currentColor 25%,
- transparent 25%,
- transparent 75%,
- currentColor 75%,
- currentColor 100%
- ),
- linear-gradient(
- 45deg,
- currentColor 25%,
- rgb(115 115 115) 25%,
- rgb(115 115 115) 75%,
- currentColor 75%,
- currentColor 100%
- );
-}
-
-@keyframes indeterminate {
- 0% {
- transform: translateX(0) scaleX(0);
- }
- 40% {
- transform: translateX(0%) scaleX(0.2);
- }
- 100% {
- transform: translateX(100%) scaleX(1);
- }
-}
-
-.indeterminate {
- transform-origin: 0% 50%;
- animation-duration: 1.5s;
- animation-iteration-count: infinite;
- animation-name: indeterminate;
-}
diff --git a/packages/editor/src/ui/README.md b/packages/editor/src/ui/README.md
deleted file mode 100644
index 83995cd7..00000000
--- a/packages/editor/src/ui/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-This is where any pieces of UI will go that form an experience, such as the
-scene menu. For atom level components (like a button) put them in the ds folder.
diff --git a/packages/editor/src/ui/__tests__/array-input.test.tsx b/packages/editor/src/ui/__tests__/array-input.test.tsx
deleted file mode 100644
index 84301bfe..00000000
--- a/packages/editor/src/ui/__tests__/array-input.test.tsx
+++ /dev/null
@@ -1,255 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-// @vitest-environment jsdom
-import { cleanup, fireEvent, render } from "@testing-library/react";
-import { afterEach, describe, expect, it, vi } from "vitest";
-import { TupleInput } from "../array-input";
-
-describe("array input", () => {
- afterEach(cleanup);
-
- it("should callback on change", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const result = getByTestId("number-1");
-
- fireEvent.change(result, { target: { valueAsNumber: 3 } });
-
- expect(change).toHaveBeenCalledWith([3, 2]);
- expect(confirm).not.toHaveBeenCalled();
- });
-
- it("should callback on blur from any input", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const result = getByTestId("number-5");
-
- fireEvent.blur(result, { target: { valueAsNumber: 100 } });
-
- expect(confirm).toHaveBeenCalledWith([100, 6]);
- });
-
- it("should not callback when required and values are partially undefined", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
-
- const element = getByTestId("number-99");
-
- fireEvent.change(element, { target: { value: "" } });
- fireEvent.blur(element, { target: { value: "" } });
-
- expect(confirm).not.toBeCalled();
- expect(change).not.toHaveBeenCalled();
- });
-
- it("should callback when required and after being filled with numbers", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
-
- const first = getByTestId("number-200");
- const second = getByTestId("number-201");
-
- fireEvent.change(first, { target: { value: "" } });
- fireEvent.blur(first, { target: { value: "" } });
- fireEvent.change(second, { target: { value: "" } });
- fireEvent.blur(second, { target: { value: "" } });
- fireEvent.change(first, { target: { value: 1 } });
- fireEvent.blur(first, { target: { value: 1 } });
- fireEvent.change(second, { target: { value: 2 } });
- fireEvent.blur(second, { target: { value: 2 } });
-
- expect(change).toHaveBeenCalledTimes(1);
- expect(change).toHaveBeenCalledWith([1, 2]);
- expect(confirm).toHaveBeenCalledTimes(1);
- expect(confirm).toHaveBeenCalledWith([1, 2]);
- });
-
- it("should callback when optional", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const first = getByTestId("number-22");
-
- fireEvent.change(first, { target: { value: "" } });
- fireEvent.blur(first, { target: { value: "" } });
-
- expect(change).toHaveBeenCalledWith([undefined, 33]);
- expect(confirm).toHaveBeenCalledWith([undefined, 33]);
- });
-
- it("should remove optional undefined values from right to left until hitting a defined value", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const first = getByTestId("number-66");
-
- fireEvent.change(first, { target: { value: 101 } });
- fireEvent.blur(first, { target: { value: 101 } });
-
- expect(change).toHaveBeenCalledWith([101, 77]);
- expect(confirm).toHaveBeenCalledWith([101, 77]);
- });
-
- it("should remove optional undefined values from right to left until hitting a defined value", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const first = getByTestId("number-888");
-
- fireEvent.change(first, { target: { value: 666 } });
- fireEvent.blur(first, { target: { value: 666 } });
-
- expect(change).toHaveBeenCalledWith([666, undefined, 999]);
- expect(confirm).toHaveBeenCalledWith([666, undefined, 999]);
- });
-
- it("should set the first value of the tuple when the value is not an array", () => {
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-1") as HTMLInputElement;
-
- expect(element.valueAsNumber).toEqual(1);
- });
-
- it("should not callback when partial values after switching from single value", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("position[1]") as HTMLInputElement;
-
- fireEvent.change(element, { target: { value: 10 } });
-
- expect(change).not.toHaveBeenCalled();
- expect(confirm).not.toHaveBeenCalled();
- });
-});
diff --git a/packages/editor/src/ui/__tests__/litreral-union-input.test.tsx b/packages/editor/src/ui/__tests__/litreral-union-input.test.tsx
deleted file mode 100644
index 1122986a..00000000
--- a/packages/editor/src/ui/__tests__/litreral-union-input.test.tsx
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-// @vitest-environment jsdom
-import { cleanup, fireEvent, render } from "@testing-library/react";
-import { afterEach, describe, expect, it, vi } from "vitest";
-import { LiteralUnionInput } from "../literal-union-input";
-
-describe("literal union input", () => {
- afterEach(cleanup);
-
- it("should default to a false boolean literal", () => {
- const onChange = vi.fn();
- const onConfirm = vi.fn();
- const { getByTestId, getByText } = render(
-
- );
-
- const select = getByTestId("select-union") as HTMLSelectElement;
- const option = getByText("false") as HTMLOptionElement;
-
- expect(select.value).toEqual(option.value);
- });
-
- it("should callback with a boolean value", () => {
- const onChange = vi.fn();
- const onConfirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const select = getByTestId("select-union") as HTMLSelectElement;
-
- fireEvent.change(select, { target: { value: "0" } });
-
- expect(onChange).toHaveBeenCalledWith(false);
- });
-
- it("should callback with a numeric value", () => {
- const onChange = vi.fn();
- const onConfirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const select = getByTestId("select-union") as HTMLSelectElement;
-
- fireEvent.change(select, { target: { value: "1" } });
-
- expect(onChange).toHaveBeenCalledWith(123);
- });
-
- it("should callback with a string value", () => {
- const onChange = vi.fn();
- const onConfirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const select = getByTestId("select-union") as HTMLSelectElement;
-
- fireEvent.change(select, { target: { value: "1" } });
-
- expect(onChange).toHaveBeenCalledWith("foo");
- });
-
- it("should not callback if value is already set", () => {
- const onChange = vi.fn();
- const onConfirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const select = getByTestId("select-union") as HTMLSelectElement;
-
- fireEvent.change(select, { target: { value: "0" } });
-
- expect(onChange).not.toHaveBeenCalled();
- });
-});
diff --git a/packages/editor/src/ui/__tests__/number-input.test.tsx b/packages/editor/src/ui/__tests__/number-input.test.tsx
deleted file mode 100644
index 68d36ff4..00000000
--- a/packages/editor/src/ui/__tests__/number-input.test.tsx
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-// @vitest-environment jsdom
-import {
- cleanup,
- fireEvent,
- render,
- waitFor,
- waitForElementToBeRemoved,
-} from "@testing-library/react";
-import { afterEach, describe, expect, it, vi } from "vitest";
-import { NumberInput } from "../number-input";
-import { PropTagContext } from "../prop-input";
-
-describe("number input", () => {
- afterEach(cleanup);
-
- it("should transform the set value", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
- (value || 0) + 10,
- out: (value) => (value || 0) - 10,
- }}
- />
- );
-
- const element = getByTestId("number-10") as HTMLInputElement;
-
- expect(element.value).toEqual("20");
- });
-
- it("should should callback with the transformed value", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
- (value || 0) + 10,
- out: (value) => (value || 0) - 10,
- }}
- />
- );
- const element = getByTestId("number-11") as HTMLInputElement;
-
- fireEvent.change(element, { target: { value: 19 } });
- fireEvent.blur(element, { target: { value: 19 } });
-
- expect(change).toHaveBeenCalledWith(9);
- });
-
- it("should decrement input", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByLabelText } = render(
-
- );
- const element = getByLabelText("Decrease by 0.02");
-
- fireEvent.click(element);
- fireEvent.blur(element);
-
- expect(change).toHaveBeenCalledWith(9.98);
- expect(confirm).toHaveBeenCalledWith(9.98);
- });
-
- it("should increment input", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByLabelText } = render(
-
- );
- const element = getByLabelText("Increase by 0.02");
-
- fireEvent.click(element);
- fireEvent.blur(element);
-
- expect(change).toHaveBeenCalledWith(10.02);
- expect(confirm).toHaveBeenCalledWith(10.02);
- });
-
- it("should clear value", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByLabelText } = render(
-
- );
- const element = getByLabelText("Clear value");
-
- fireEvent.click(element);
- fireEvent.blur(element);
-
- expect(change).toHaveBeenCalledWith(undefined);
- expect(confirm).toHaveBeenCalledWith(undefined);
- });
-
- it("should focus the input when not initiating a drag", async () => {
- const { getByTestId } = render(
- {}}
- onConfirm={() => {}}
- />
- );
- const element = getByTestId("number-10");
-
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
- fireEvent.mouseUp(element);
-
- expect(document.activeElement).toBe(element);
- });
-
- it("should not focus the input when initiating a drag", async () => {
- const { getByTestId } = render(
- {}}
- onConfirm={() => {}}
- />
- );
- const element = getByTestId("number-10");
-
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
- fireEvent.mouseMove(element);
- fireEvent.mouseUp(element);
-
- expect(document.activeElement).not.toBe(element);
- });
-
- it("should blur away from an iframe on mouse down", () => {
- const { getByTestId } = render(
- <>
-
- {}}
- onConfirm={() => {}}
- />
- >
- );
- const iframe = getByTestId("iframe");
- iframe.focus();
- const element = getByTestId("number-10");
-
- fireEvent.mouseDown(element);
-
- expect(document.activeElement).not.toBe(iframe);
- });
-
- it("should do nothing when there has been no movement in a drag", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10");
-
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
- fireEvent.mouseMove(element, { clientX: 0 });
-
- expect(change).toHaveBeenCalledWith(10);
- });
-
- it("should increment when dragging movement is positive", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10");
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
-
- fireEvent.mouseMove(element, { clientX: 1 });
-
- expect(change).toHaveBeenCalledWith(10.02);
- });
-
- it("should multiply the step during a drag when pressing ctrl", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10.2");
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
- await fireEvent.keyDown(document, { ctrlKey: true });
-
- fireEvent.mouseMove(element, { clientX: 1 });
-
- // TODO: This should be capped to multiples of 0.5
- // E.g. Round up or down. So this should round down to 10.5.
- expect(change).toHaveBeenCalledWith(10.7);
- });
-
- it("should reduce the step during a drag when pressing shift", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10.2");
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
- await fireEvent.keyDown(document, { shiftKey: true });
-
- fireEvent.mouseMove(element, { clientX: 1 });
-
- expect(change).toHaveBeenCalledWith(10.202);
- });
-
- it("should decrement when dragging movement is negative", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10");
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
-
- fireEvent.mouseMove(element, { clientX: -1 });
-
- expect(change).toHaveBeenCalledWith(9.98);
- });
-
- it("should multiply the change when movement is over multiple pixels", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10");
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
-
- fireEvent.mouseMove(element, { clientX: 100 });
-
- expect(change).toHaveBeenCalledWith(12);
- });
-
- it("should callback with confirm when completing a drag", async () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10");
- fireEvent.mouseDown(element);
- await waitFor(() => getByTestId("pointer-lock"));
- fireEvent.mouseMove(element, { clientX: 100 });
-
- fireEvent.mouseUp(element);
- await waitForElementToBeRemoved(() => getByTestId("pointer-lock"));
-
- expect(confirm).toHaveBeenCalledWith(12);
- });
-
- it("should focus the input when clearing via the clear button", () => {
- const { getByLabelText, getByTestId } = render(
- {}}
- onConfirm={() => {}}
- />
- );
- const element = getByLabelText("Clear value");
- const inputElement = getByTestId("number-10");
-
- fireEvent.click(element);
-
- expect(document.activeElement).toBe(inputElement);
- });
-
- it("should not callback if value is outside max range", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
-
-
- );
- const element = getByTestId("number-10");
-
- fireEvent.change(element, { target: { value: "1000" } });
- fireEvent.blur(element);
-
- expect(change).not.toHaveBeenCalled();
- expect(confirm).not.toHaveBeenCalled();
- });
-
- it("should not callback if value is outside max range", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
-
-
- );
- const element = getByTestId("number-10");
-
- fireEvent.change(element, { target: { value: "-1000" } });
- fireEvent.blur(element);
-
- expect(change).not.toHaveBeenCalled();
- expect(confirm).not.toHaveBeenCalled();
- });
-
- it("should not callback if nothing has changed", () => {
- const change = vi.fn();
- const confirm = vi.fn();
- const { getByTestId } = render(
-
- );
- const element = getByTestId("number-10");
-
- fireEvent.change(element, { target: { value: "10" } });
- fireEvent.blur(element);
-
- expect(change).not.toHaveBeenCalled();
- expect(confirm).not.toHaveBeenCalled();
- });
-});
diff --git a/packages/editor/src/ui/array-input.tsx b/packages/editor/src/ui/array-input.tsx
deleted file mode 100644
index 965ac118..00000000
--- a/packages/editor/src/ui/array-input.tsx
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import type { TupleType } from "@triplex/server";
-import { useRef } from "react";
-import { PropInput } from "./prop-input";
-
-function merge(a: unknown[], b: Record) {
- const c = [...a];
-
- for (const key in b) {
- const index = Number(key);
- if (Number.isNaN(index)) {
- throw new Error("invariant");
- }
-
- c[index] = b[index];
- }
-
- return c;
-}
-
-function isAnyRequiredValueUndefined(
- tupleTypes: TupleType["shape"],
- nextValue: unknown[]
-) {
- for (let i = 0; i < tupleTypes.length; i++) {
- const type = tupleTypes[i];
- const value = nextValue[i];
- const isUndefinedOrEmptyString = value === undefined || value === "";
-
- if (isUndefinedOrEmptyString && "required" in type && type.required) {
- return true;
- }
- }
-
- return false;
-}
-
-function dropUnneededOptionalValues(
- valueDef: TupleType["shape"],
- nextValues: unknown[]
-) {
- const clearedValues: unknown[] = [];
-
- let foundDefinedValue = false;
-
- for (let i = nextValues.length - 1; i >= 0; i--) {
- const value = nextValues[i];
- const isUndefinedOrEmptyString = value === undefined || value === "";
- const type = valueDef[i];
-
- if (
- !foundDefinedValue &&
- isUndefinedOrEmptyString &&
- ("required" in type ? !type.required : true)
- ) {
- // While we haven't found any defined values, we can skip undefined optional ones
- } else {
- foundDefinedValue = true;
- clearedValues.unshift(value);
- }
- }
-
- return clearedValues;
-}
-
-export function TupleInput({
- column,
- line,
- name,
- onChange,
- onConfirm,
- path,
- testId,
- value,
- values,
-}: {
- column?: number;
- line?: number;
- name: string;
- onChange: (value: unknown[]) => void;
- onConfirm: (value: unknown[]) => void;
- path: string;
- required?: boolean;
- testId?: string;
- value: unknown[] | unknown;
- values: TupleType["shape"];
-}) {
- const defaultValue = Array.isArray(value) ? value : [value];
- const intermediateValues = useRef>({});
-
- return (
- <>
- {values.map((val, index) => {
- const onChangeHandler = (value: unknown) => {
- intermediateValues.current[index] = value;
-
- const nextValue = merge(defaultValue, intermediateValues.current);
-
- if (isAnyRequiredValueUndefined(values, nextValue)) {
- return;
- }
-
- onChange(dropUnneededOptionalValues(values, nextValue));
- };
-
- const onConfirmHandler = (value: unknown) => {
- intermediateValues.current[index] = value;
-
- const nextValue = merge(defaultValue, intermediateValues.current);
-
- if (isAnyRequiredValueUndefined(values, nextValue)) {
- return;
- }
-
- onConfirm(dropUnneededOptionalValues(values, nextValue));
- intermediateValues.current = {};
- };
-
- return (
-
- );
- })}
- >
- );
-}
diff --git a/packages/editor/src/ui/assets-drawer.tsx b/packages/editor/src/ui/assets-drawer.tsx
deleted file mode 100644
index 8e074474..00000000
--- a/packages/editor/src/ui/assets-drawer.tsx
+++ /dev/null
@@ -1,394 +0,0 @@
-/**
- * Copyright (c) Michael Dougall. All rights reserved.
- *
- * This source code is licensed under the GPL-3.0 license found in the LICENSE
- * file in the root directory of this source tree.
- */
-import { CaretDownIcon, CaretRightIcon } from "@radix-ui/react-icons";
-import type {
- Folder as FolderType,
- ProjectAsset as ProjectAssetType,
- ProjectCustomComponent,
- ProjectHostComponent,
-} from "@triplex/server";
-import {
- preloadSubscription,
- useLazySubscription,
- useSubscription,
-} from "@triplex/ws-client";
-import { createContext, Suspense, useContext, useState } from "react";
-import { cn } from "../ds/cn";
-import { Drawer } from "../ds/drawer";
-import { ScrollContainer } from "../ds/scroll-container";
-import { useAssetsDrawer } from "../stores/assets-drawer";
-import { useScene } from "../stores/scene";
-import { titleCase } from "../util/string";
-import { StringInput } from "./string-input";
-
-function ProjectAsset({
- asset,
- name,
- onClick,
-}: {
- asset: ProjectHostComponent | ProjectCustomComponent | ProjectAssetType;
- name: string;
- onClick: () => void;
-}) {
- const { addComponent } = useScene();
- const target = useAssetsDrawer((store) => store.shown);
-
- const onClickHandler = () => {
- const targetData =
- typeof target === "object"
- ? ({ action: "child", ...target } as const)
- : undefined;
-
- switch (asset.type) {
- case "host":
- addComponent({
- target: targetData,
- type: { name, props: {}, type: "host" },
- });
- break;
-
- case "custom":
- addComponent({
- target: targetData,
- type: {
- exportName: asset.exportName,
- name: asset.name,
- path: asset.path,
- props: {},
- type: "custom",
- },
- });
- break;
-
- case "asset":
- addComponent({
- type: {
- exportName: "Gltf",
- name: "Gltf",
- path: "@react-three/drei",
- props: { src: asset.path },
- type: "custom",
- },
- });
- break;
- }
-
- onClick();
- };
-
- return (
-
- );
-}
-
-const FolderContext = createContext(0);
-
-function Folder({
- children = [],
- filesCount = 0,
- isSelected,
- onClick,
- text,
-}: {
- children?: (JSX.Element | JSX.Element[])[];
- filesCount?: number;
- isSelected?: boolean;
- onClick?: () => void;
- text: string;
-}) {
- const defaultExpanded =
- Array.isArray(children) && children.length > 5 ? false : true;
- const [isExpanded, setExpanded] = useState(defaultExpanded);
- const level = useContext(FolderContext);
- const hasChildrenFolders = children.length > 0;
-
- return (
-
-
-
- {hasChildrenFolders && isExpanded && (
-