@tomorrowevening/hermes 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +10 -0
  3. package/dist/hermes.js +1202 -0
  4. package/dist/hermes.umd.cjs +29 -0
  5. package/dist/images/debug/icon_camera.png +0 -0
  6. package/dist/images/debug/icon_folder.png +0 -0
  7. package/dist/images/debug/icon_interactive.png +0 -0
  8. package/dist/images/debug/icon_lights.png +0 -0
  9. package/dist/images/debug/icon_refresh.png +0 -0
  10. package/dist/images/debug/icon_ui.png +0 -0
  11. package/dist/images/debug/icon_utils.png +0 -0
  12. package/dist/images/debug/icon_world.png +0 -0
  13. package/dist/style.css +1 -0
  14. package/package.json +63 -0
  15. package/src/core/Application.ts +69 -0
  16. package/src/core/RemoteController.ts +135 -0
  17. package/src/core/remote/BaseRemote.ts +16 -0
  18. package/src/core/remote/RemoteComponents.ts +32 -0
  19. package/src/core/remote/RemoteTheatre.ts +117 -0
  20. package/src/core/remote/RemoteTweakpane.ts +176 -0
  21. package/src/core/types.ts +43 -0
  22. package/src/editor/Editor.tsx +15 -0
  23. package/src/editor/components/Draggable.tsx +40 -0
  24. package/src/editor/components/DraggableItem.tsx +22 -0
  25. package/src/editor/components/Dropdown.tsx +30 -0
  26. package/src/editor/components/DropdownItem.tsx +64 -0
  27. package/src/editor/components/NavButton.tsx +11 -0
  28. package/src/editor/components/icons/CloseIcon.tsx +7 -0
  29. package/src/editor/components/icons/DragIcon.tsx +9 -0
  30. package/src/editor/components/types.ts +41 -0
  31. package/src/editor/global.ts +13 -0
  32. package/src/editor/sceneHierarchy/ChildObject.tsx +56 -0
  33. package/src/editor/sceneHierarchy/ContainerObject.tsx +12 -0
  34. package/src/editor/sceneHierarchy/SceneHierarchy.tsx +77 -0
  35. package/src/editor/sceneHierarchy/types.ts +10 -0
  36. package/src/editor/sceneHierarchy/utils.ts +25 -0
  37. package/src/editor/scss/_debug.scss +68 -0
  38. package/src/editor/scss/_draggable.scss +43 -0
  39. package/src/editor/scss/_dropdown.scss +83 -0
  40. package/src/editor/scss/_sceneHierarchy.scss +170 -0
  41. package/src/editor/scss/_theme.scss +9 -0
  42. package/src/editor/scss/index.scss +58 -0
  43. package/src/editor/utils.ts +20 -0
  44. package/src/example/App.css +6 -0
  45. package/src/example/App.tsx +88 -0
  46. package/src/example/constants.ts +13 -0
  47. package/src/example/index.scss +37 -0
  48. package/src/example/main.tsx +75 -0
  49. package/src/library.ts +16 -0
  50. package/src/vite-env.d.ts +1 -0
  51. package/types/core/Application.d.ts +21 -0
  52. package/types/core/RemoteController.d.ts +2 -0
  53. package/types/core/remote/BaseRemote.d.ts +6 -0
  54. package/types/core/remote/RemoteComponents.d.ts +7 -0
  55. package/types/core/remote/RemoteDebug.d.ts +23 -0
  56. package/types/core/remote/RemoteTheatre.d.ts +16 -0
  57. package/types/core/remote/RemoteTweakpane.d.ts +23 -0
  58. package/types/core/types.d.ts +13 -0
  59. package/types/debug/Editor.d.ts +8 -0
  60. package/types/debug/components/Draggable.d.ts +2 -0
  61. package/types/debug/components/DraggableItem.d.ts +2 -0
  62. package/types/debug/components/Dropdown.d.ts +2 -0
  63. package/types/debug/components/DropdownItem.d.ts +2 -0
  64. package/types/debug/components/NavButton.d.ts +5 -0
  65. package/types/debug/components/icons/CloseIcon.d.ts +2 -0
  66. package/types/debug/components/icons/DragIcon.d.ts +2 -0
  67. package/types/debug/components/types.d.ts +31 -0
  68. package/types/debug/global.d.ts +9 -0
  69. package/types/debug/sceneHierarchy/ChildObject.d.ts +2 -0
  70. package/types/debug/sceneHierarchy/ContainerObject.d.ts +2 -0
  71. package/types/debug/sceneHierarchy/SceneHierarchy.d.ts +13 -0
  72. package/types/debug/sceneHierarchy/types.d.ts +8 -0
  73. package/types/debug/sceneHierarchy/utils.d.ts +2 -0
  74. package/types/debug/utils.d.ts +4 -0
  75. package/types/editor/Editor.d.ts +8 -0
  76. package/types/editor/components/Draggable.d.ts +2 -0
  77. package/types/editor/components/DraggableItem.d.ts +2 -0
  78. package/types/editor/components/Dropdown.d.ts +2 -0
  79. package/types/editor/components/DropdownItem.d.ts +2 -0
  80. package/types/editor/components/NavButton.d.ts +5 -0
  81. package/types/editor/components/icons/CloseIcon.d.ts +2 -0
  82. package/types/editor/components/icons/DragIcon.d.ts +2 -0
  83. package/types/editor/components/types.d.ts +31 -0
  84. package/types/editor/global.d.ts +9 -0
  85. package/types/editor/sceneHierarchy/ChildObject.d.ts +2 -0
  86. package/types/editor/sceneHierarchy/ContainerObject.d.ts +2 -0
  87. package/types/editor/sceneHierarchy/SceneHierarchy.d.ts +13 -0
  88. package/types/editor/sceneHierarchy/types.d.ts +8 -0
  89. package/types/editor/sceneHierarchy/utils.d.ts +2 -0
  90. package/types/editor/utils.d.ts +4 -0
  91. package/types/example/App.d.ts +3 -0
  92. package/types/example/constants.d.ts +3 -0
  93. package/types/example/main.d.ts +1 -0
  94. package/types/library.d.ts +14 -0
@@ -0,0 +1,29 @@
1
+ (function(v,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("@theatre/core"),require("tweakpane"),require("@tweakpane/plugin-essentials"),require("three"),require("react"),require("framer-motion"),require("@theatre/studio")):typeof define=="function"&&define.amd?define(["exports","@theatre/core","tweakpane","@tweakpane/plugin-essentials","three","react","framer-motion","@theatre/studio"],x):(v=typeof globalThis<"u"?globalThis:v||self,x(v.Hermes={},v["Theatre Core"],v.tweakpane,v["tweakpane-plugin-essentials"],v.Three,v.React,v["framer-motion"],v["Theatre Studio"]))})(this,function(v,x,A,Ve,Ge,N,le,W){"use strict";var $t=Object.defineProperty;var Yt=(v,x,A)=>x in v?$t(v,x,{enumerable:!0,configurable:!0,writable:!0,value:A}):v[x]=A;var C=(v,x,A)=>(Yt(v,typeof x!="symbol"?x+"":x,A),A);function qe(n){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const r in n)if(r!=="default"){const o=Object.getOwnPropertyDescriptor(n,r);Object.defineProperty(a,r,o.get?o:{enumerable:!0,get:()=>n[r]})}}return a.default=n,Object.freeze(a)}const ze=qe(Ve);class q{constructor(a){C(this,"app");this.app=a}dispose(){}}class ue extends q{constructor(a){super(a)}selectDropdown(a,r){this.app.send({event:"selectComponent",data:{dropdown:a,value:r}})}updateDropdown(a,r){this.app.send({event:"draggableListUpdate",data:{dropdown:a,value:r}})}}function Je(){return Math.round(Math.random()*1e6).toString()}function Ke(n){return n.r!==void 0&&n.g!==void 0&&n.b!==void 0}const de=()=>{};class fe extends q{constructor(r,o,i){super(r);C(this,"project");C(this,"sheets");C(this,"sheetObjects");C(this,"sheetObjectCBs");C(this,"sheetObjectUnsubscribe");this.project=x.getProject(o,i),this.sheets=new Map,this.sheetObjects=new Map,this.sheetObjectCBs=new Map,this.sheetObjectUnsubscribe=new Map}dispose(){this.project=void 0,this.sheets=new Map,this.sheetObjects=new Map,this.sheetObjectCBs=new Map,this.sheetObjectUnsubscribe=new Map}sheet(r){var i;if(this.project===void 0){console.error("Theatre Project hasn't been created yet.");return}let o=this.sheets.get(r);return o!==void 0||(o=(i=this.project)==null?void 0:i.sheet(r),this.sheets.set(r,o)),o}sheetObject(r,o,i,l){if(this.project===void 0){console.error("Theatre Project hasn't been created yet.");return}const E=this.sheets.get(r);if(E===void 0)return;const m=`${r}_${o}`;let d=this.sheetObjects.get(m);if(d!==void 0)return d=E.object(o,{...i,...d.value},{reconfigure:!0}),d;d=E.object(o,i),this.sheetObjects.set(m,d),this.sheetObjectCBs.set(m,l!==void 0?l:de);const y=d.onValuesChange(p=>{if(this.app.editor){for(const S in p){const _=p[S];typeof _=="object"&&Ke(_)&&(p[S]={r:_.r,g:_.g,b:_.b,a:_.a})}this.app.send({event:"updateSheetObject",data:{sheetObject:m,values:p}})}else{const S=this.sheetObjectCBs.get(m);S!==void 0&&S(p)}});return this.sheetObjectUnsubscribe.set(m,y),d}unsubscribe(r){if(this.project===void 0){console.error("Theatre Project hasn't been created yet.");return}const o=`${r.address.sheetId}_${r.address.objectKey}`,i=this.sheetObjectUnsubscribe.get(o);i!==void 0&&i()}}class he extends q{constructor(r){super(r);C(this,"appTab");C(this,"systemTab");C(this,"utilsTab");C(this,"bindCBs");C(this,"buttonCBs");C(this,"pane");C(this,"appCallbacks",0);C(this,"editorCallbacks",0);this.bindCBs=new Map,this.buttonCBs=new Map,r.editor&&this.createGUI()}createGUI(){this.pane=new A.Pane({title:"GUI"}),this.pane.registerPlugin(ze);const r=this.pane.element.parentElement;r.style.left="50%",r.style.top="0",r.style.maxHeight="100%",r.style.overflowX="hidden",r.style.overflowY="auto",r.style.transform="translateX(-50%)",r.style.width="300px",r.style.zIndex="100";const o=this.pane.addTab({pages:[{title:"App"},{title:"System"},{title:"Tools"}]});this.appTab=o.pages[0],this.systemTab=o.pages[1],this.utilsTab=o.pages[2]}dispose(){var r,o,i,l;this.bindCBs.clear(),this.buttonCBs.clear(),this.appCallbacks=0,this.editorCallbacks=0,this.app.editor&&((r=this.appTab)==null||r.dispose(),(o=this.systemTab)==null||o.dispose(),(i=this.utilsTab)==null||i.dispose(),(l=this.pane)==null||l.dispose(),this.appTab=void 0,this.systemTab=void 0,this.utilsTab=void 0,this.pane=void 0)}addFolder(r,o=void 0,i=void 0){if(this.app.editor)return this.pane===void 0&&this.createGUI(),(i!==void 0?i:this.appTab).addFolder({title:r,...o});this.app.send({event:"addFolder",data:{name:r,params:o,parent:i}})}get bindID(){return`debug_${Math.max(this.appCallbacks,this.editorCallbacks)}`}bind(r,o,i,l=void 0){const E=this.bindID,m=i.onChange!==void 0?i.onChange:de;this.bindCBs.set(E,m),this.app.editor?(this.pane===void 0&&this.createGUI(),(l!==void 0?l:this.appTab).addBinding(r,o,i).on("change",y=>{this.app.send({event:"updateBind",data:{id:E,value:y.value}})}),this.editorCallbacks++):(this.app.send({event:"bindObject",data:{id:E,name:o,params:i,parent:l}}),this.appCallbacks++)}triggerBind(r,o){const i=this.bindCBs.get(r);i!==void 0?i(o):console.warn(`No callback for: ${r}`,o)}button(r,o,i=void 0){const l=this.bindID;this.buttonCBs.set(l,o),this.app.editor?(this.pane===void 0&&this.createGUI(),(i!==void 0?i:this.appTab).addButton({title:r}).on("click",()=>{this.app.send({event:"clickButton",data:{id:l}})}),this.editorCallbacks++):(this.app.send({event:"addButton",data:{id:l,name:r,callback:o,parent:i}}),this.appCallbacks++)}triggerButton(r){const o=this.buttonCBs.get(r);o!==void 0&&o()}}class Xe{constructor(a,r){C(this,"components");C(this,"debug");C(this,"theatre");C(this,"mode","listener");C(this,"channel");this.editor=a&&document.location.hash.search(r)>-1,a&&(this.channel=new BroadcastChannel("theatre"))}setupComponents(){this.components=new ue(this)}setupGUI(){this.debug=new he(this)}setupTheatre(a,r){this.theatre=new fe(this,a,r)}dispose(){var a,r,o;(a=this.components)==null||a.dispose(),(r=this.debug)==null||r.dispose(),(o=this.theatre)==null||o.dispose()}send(a){this.mode==="editor"&&this.channel!==void 0&&this.channel.postMessage(a)}listen(a){this.mode==="listener"&&this.channel!==void 0&&(this.channel.onmessage=r=>{a(r.data)})}get editor(){return this.mode==="editor"}set editor(a){a&&(this.mode="editor",document.title+=" - Editor")}}const k=new Ge.EventDispatcher,P={SELECT_DROPDOWN:"ToolEvents::selectDropdown",DRAG_UPDATE:"ToolEvents::dragUpdate",INSPECT_ITEM:"ToolEvents::inspectItem",REFRESH_SCENE:"ToolEvents::refreshScene",SET_SCENE:"ToolEvents::setScene"};var Q={exports:{}},$={};/**
2
+ * @license React
3
+ * react-jsx-runtime.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */var ve;function Ze(){if(ve)return $;ve=1;var n=N,a=Symbol.for("react.element"),r=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function E(m,d,y){var p,S={},_=null,F=null;y!==void 0&&(_=""+y),d.key!==void 0&&(_=""+d.key),d.ref!==void 0&&(F=d.ref);for(p in d)o.call(d,p)&&!l.hasOwnProperty(p)&&(S[p]=d[p]);if(m&&m.defaultProps)for(p in d=m.defaultProps,d)S[p]===void 0&&(S[p]=d[p]);return{$$typeof:a,type:m,key:_,ref:F,props:S,_owner:i.current}}return $.Fragment=r,$.jsx=E,$.jsxs=E,$}var Y={};/**
10
+ * @license React
11
+ * react-jsx-runtime.development.js
12
+ *
13
+ * Copyright (c) Facebook, Inc. and its affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ */var pe;function Qe(){return pe||(pe=1,process.env.NODE_ENV!=="production"&&function(){var n=N,a=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),i=Symbol.for("react.strict_mode"),l=Symbol.for("react.profiler"),E=Symbol.for("react.provider"),m=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),y=Symbol.for("react.suspense"),p=Symbol.for("react.suspense_list"),S=Symbol.for("react.memo"),_=Symbol.for("react.lazy"),F=Symbol.for("react.offscreen"),H=Symbol.iterator,ot="@@iterator";function ct(e){if(e===null||typeof e!="object")return null;var t=H&&e[H]||e[ot];return typeof t=="function"?t:null}var B=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function T(e){{for(var t=arguments.length,s=new Array(t>1?t-1:0),c=1;c<t;c++)s[c-1]=arguments[c];lt("error",e,s)}}function lt(e,t,s){{var c=B.ReactDebugCurrentFrame,b=c.getStackAddendum();b!==""&&(t+="%s",s=s.concat([b]));var g=s.map(function(h){return String(h)});g.unshift("Warning: "+t),Function.prototype.apply.call(console[e],console,g)}}var ut=!1,dt=!1,ft=!1,ht=!1,vt=!1,Ce;Ce=Symbol.for("react.module.reference");function pt(e){return!!(typeof e=="string"||typeof e=="function"||e===o||e===l||vt||e===i||e===y||e===p||ht||e===F||ut||dt||ft||typeof e=="object"&&e!==null&&(e.$$typeof===_||e.$$typeof===S||e.$$typeof===E||e.$$typeof===m||e.$$typeof===d||e.$$typeof===Ce||e.getModuleId!==void 0))}function bt(e,t,s){var c=e.displayName;if(c)return c;var b=t.displayName||t.name||"";return b!==""?s+"("+b+")":s}function Se(e){return e.displayName||"Context"}function D(e){if(e==null)return null;if(typeof e.tag=="number"&&T("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case o:return"Fragment";case r:return"Portal";case l:return"Profiler";case i:return"StrictMode";case y:return"Suspense";case p:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case m:var t=e;return Se(t)+".Consumer";case E:var s=e;return Se(s._context)+".Provider";case d:return bt(e,e.render,"ForwardRef");case S:var c=e.displayName||null;return c!==null?c:D(e.type)||"Memo";case _:{var b=e,g=b._payload,h=b._init;try{return D(h(g))}catch{return null}}}return null}var M=Object.assign,V=0,je,_e,Re,Te,we,xe,Oe;function ke(){}ke.__reactDisabledLog=!0;function mt(){{if(V===0){je=console.log,_e=console.info,Re=console.warn,Te=console.error,we=console.group,xe=console.groupCollapsed,Oe=console.groupEnd;var e={configurable:!0,enumerable:!0,value:ke,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}V++}}function gt(){{if(V--,V===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:M({},e,{value:je}),info:M({},e,{value:_e}),warn:M({},e,{value:Re}),error:M({},e,{value:Te}),group:M({},e,{value:we}),groupCollapsed:M({},e,{value:xe}),groupEnd:M({},e,{value:Oe})})}V<0&&T("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var te=B.ReactCurrentDispatcher,re;function z(e,t,s){{if(re===void 0)try{throw Error()}catch(b){var c=b.stack.trim().match(/\n( *(at )?)/);re=c&&c[1]||""}return`
18
+ `+re+e}}var ne=!1,J;{var Et=typeof WeakMap=="function"?WeakMap:Map;J=new Et}function Pe(e,t){if(!e||ne)return"";{var s=J.get(e);if(s!==void 0)return s}var c;ne=!0;var b=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var g;g=te.current,te.current=null,mt();try{if(t){var h=function(){throw Error()};if(Object.defineProperty(h.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(h,[])}catch(I){c=I}Reflect.construct(e,[],h)}else{try{h.call()}catch(I){c=I}e.call(h.prototype)}}else{try{throw Error()}catch(I){c=I}e()}}catch(I){if(I&&c&&typeof I.stack=="string"){for(var f=I.stack.split(`
19
+ `),w=c.stack.split(`
20
+ `),j=f.length-1,R=w.length-1;j>=1&&R>=0&&f[j]!==w[R];)R--;for(;j>=1&&R>=0;j--,R--)if(f[j]!==w[R]){if(j!==1||R!==1)do if(j--,R--,R<0||f[j]!==w[R]){var O=`
21
+ `+f[j].replace(" at new "," at ");return e.displayName&&O.includes("<anonymous>")&&(O=O.replace("<anonymous>",e.displayName)),typeof e=="function"&&J.set(e,O),O}while(j>=1&&R>=0);break}}}finally{ne=!1,te.current=g,gt(),Error.prepareStackTrace=b}var L=e?e.displayName||e.name:"",He=L?z(L):"";return typeof e=="function"&&J.set(e,He),He}function yt(e,t,s){return Pe(e,!1)}function Ct(e){var t=e.prototype;return!!(t&&t.isReactComponent)}function K(e,t,s){if(e==null)return"";if(typeof e=="function")return Pe(e,Ct(e));if(typeof e=="string")return z(e);switch(e){case y:return z("Suspense");case p:return z("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case d:return yt(e.render);case S:return K(e.type,t,s);case _:{var c=e,b=c._payload,g=c._init;try{return K(g(b),t,s)}catch{}}}return""}var X=Object.prototype.hasOwnProperty,De={},Ie=B.ReactDebugCurrentFrame;function Z(e){if(e){var t=e._owner,s=K(e.type,e._source,t?t.type:null);Ie.setExtraStackFrame(s)}else Ie.setExtraStackFrame(null)}function St(e,t,s,c,b){{var g=Function.call.bind(X);for(var h in e)if(g(e,h)){var f=void 0;try{if(typeof e[h]!="function"){var w=Error((c||"React class")+": "+s+" type `"+h+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[h]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw w.name="Invariant Violation",w}f=e[h](t,h,c,s,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(j){f=j}f&&!(f instanceof Error)&&(Z(b),T("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",c||"React class",s,h,typeof f),Z(null)),f instanceof Error&&!(f.message in De)&&(De[f.message]=!0,Z(b),T("Failed %s type: %s",s,f.message),Z(null))}}}var jt=Array.isArray;function ae(e){return jt(e)}function _t(e){{var t=typeof Symbol=="function"&&Symbol.toStringTag,s=t&&e[Symbol.toStringTag]||e.constructor.name||"Object";return s}}function Rt(e){try{return Ne(e),!1}catch{return!0}}function Ne(e){return""+e}function Ae(e){if(Rt(e))return T("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",_t(e)),Ne(e)}var G=B.ReactCurrentOwner,Tt={key:!0,ref:!0,__self:!0,__source:!0},Fe,Me,ie;ie={};function wt(e){if(X.call(e,"ref")){var t=Object.getOwnPropertyDescriptor(e,"ref").get;if(t&&t.isReactWarning)return!1}return e.ref!==void 0}function xt(e){if(X.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function Ot(e,t){if(typeof e.ref=="string"&&G.current&&t&&G.current.stateNode!==t){var s=D(G.current.type);ie[s]||(T('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref',D(G.current.type),e.ref),ie[s]=!0)}}function kt(e,t){{var s=function(){Fe||(Fe=!0,T("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",t))};s.isReactWarning=!0,Object.defineProperty(e,"key",{get:s,configurable:!0})}}function Pt(e,t){{var s=function(){Me||(Me=!0,T("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",t))};s.isReactWarning=!0,Object.defineProperty(e,"ref",{get:s,configurable:!0})}}var Dt=function(e,t,s,c,b,g,h){var f={$$typeof:a,type:e,key:t,ref:s,props:h,_owner:g};return f._store={},Object.defineProperty(f._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(f,"_self",{configurable:!1,enumerable:!1,writable:!1,value:c}),Object.defineProperty(f,"_source",{configurable:!1,enumerable:!1,writable:!1,value:b}),Object.freeze&&(Object.freeze(f.props),Object.freeze(f)),f};function It(e,t,s,c,b){{var g,h={},f=null,w=null;s!==void 0&&(Ae(s),f=""+s),xt(t)&&(Ae(t.key),f=""+t.key),wt(t)&&(w=t.ref,Ot(t,b));for(g in t)X.call(t,g)&&!Tt.hasOwnProperty(g)&&(h[g]=t[g]);if(e&&e.defaultProps){var j=e.defaultProps;for(g in j)h[g]===void 0&&(h[g]=j[g])}if(f||w){var R=typeof e=="function"?e.displayName||e.name||"Unknown":e;f&&kt(h,R),w&&Pt(h,R)}return Dt(e,f,w,b,c,G.current,h)}}var se=B.ReactCurrentOwner,Be=B.ReactDebugCurrentFrame;function U(e){if(e){var t=e._owner,s=K(e.type,e._source,t?t.type:null);Be.setExtraStackFrame(s)}else Be.setExtraStackFrame(null)}var oe;oe=!1;function ce(e){return typeof e=="object"&&e!==null&&e.$$typeof===a}function Ue(){{if(se.current){var e=D(se.current.type);if(e)return`
22
+
23
+ Check the render method of \``+e+"`."}return""}}function Nt(e){{if(e!==void 0){var t=e.fileName.replace(/^.*[\\\/]/,""),s=e.lineNumber;return`
24
+
25
+ Check your code at `+t+":"+s+"."}return""}}var Le={};function At(e){{var t=Ue();if(!t){var s=typeof e=="string"?e:e.displayName||e.name;s&&(t=`
26
+
27
+ Check the top-level render call using <`+s+">.")}return t}}function We(e,t){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var s=At(t);if(Le[s])return;Le[s]=!0;var c="";e&&e._owner&&e._owner!==se.current&&(c=" It was passed a child from "+D(e._owner.type)+"."),U(e),T('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',s,c),U(null)}}function $e(e,t){{if(typeof e!="object")return;if(ae(e))for(var s=0;s<e.length;s++){var c=e[s];ce(c)&&We(c,t)}else if(ce(e))e._store&&(e._store.validated=!0);else if(e){var b=ct(e);if(typeof b=="function"&&b!==e.entries)for(var g=b.call(e),h;!(h=g.next()).done;)ce(h.value)&&We(h.value,t)}}}function Ft(e){{var t=e.type;if(t==null||typeof t=="string")return;var s;if(typeof t=="function")s=t.propTypes;else if(typeof t=="object"&&(t.$$typeof===d||t.$$typeof===S))s=t.propTypes;else return;if(s){var c=D(t);St(s,e.props,"prop",c,e)}else if(t.PropTypes!==void 0&&!oe){oe=!0;var b=D(t);T("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",b||"Unknown")}typeof t.getDefaultProps=="function"&&!t.getDefaultProps.isReactClassApproved&&T("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function Mt(e){{for(var t=Object.keys(e.props),s=0;s<t.length;s++){var c=t[s];if(c!=="children"&&c!=="key"){U(e),T("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",c),U(null);break}}e.ref!==null&&(U(e),T("Invalid attribute `ref` supplied to `React.Fragment`."),U(null))}}function Ye(e,t,s,c,b,g){{var h=pt(e);if(!h){var f="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(f+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var w=Nt(b);w?f+=w:f+=Ue();var j;e===null?j="null":ae(e)?j="array":e!==void 0&&e.$$typeof===a?(j="<"+(D(e.type)||"Unknown")+" />",f=" Did you accidentally export a JSX literal instead of a component?"):j=typeof e,T("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",j,f)}var R=It(e,t,s,b,g);if(R==null)return R;if(h){var O=t.children;if(O!==void 0)if(c)if(ae(O)){for(var L=0;L<O.length;L++)$e(O[L],e);Object.freeze&&Object.freeze(O)}else T("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else $e(O,e)}return e===o?Mt(R):Ft(R),R}}function Bt(e,t,s){return Ye(e,t,s,!0)}function Ut(e,t,s){return Ye(e,t,s,!1)}var Lt=Ut,Wt=Bt;Y.Fragment=o,Y.jsx=Lt,Y.jsxs=Wt}()),Y}process.env.NODE_ENV==="production"?Q.exports=Ze():Q.exports=Qe();var u=Q.exports;function ee(n){return n.title.search("<")>-1?u.jsx("button",{className:"svg",dangerouslySetInnerHTML:{__html:n.title}}):u.jsx("button",{children:n.title})}const et=u.jsxs("svg",{className:"closeIcon",width:"14",height:"14",fill:"none",stroke:"#666666",strokeMiterlimit:"10",children:[u.jsx("circle",{cx:"7",cy:"7",r:"6"}),u.jsx("line",{x1:"4",y1:"4",x2:"10",y2:"10"}),u.jsx("line",{x1:"4",y1:"10",x2:"10",y2:"4"})]}),tt=u.jsx("svg",{className:"dragIcon",width:"14",height:"14",fill:"#666666",stroke:"none",children:u.jsx("path",{d:`M10.43,4H3.57C3.26,4,3,4.22,3,4.5v1C3,5.78,3.26,6,3.57,6h6.86C10.74,6,11,5.78,11,5.5v-1
28
+ C11,4.22,10.74,4,10.43,4z M10.43,8H3.57C3.26,8,3,8.22,3,8.5v1C3,9.78,3.26,10,3.57,10h6.86C10.74,10,11,9.78,11,9.5v-1
29
+ C11,8.22,10.74,8,10.43,8z`})});function be(n){return u.jsx(le.Reorder.Item,{value:n.title,children:u.jsxs("div",{children:[tt,u.jsx("span",{children:n.title}),u.jsx("button",{className:"closeIcon",onClick:()=>{n.onDelete(n.index)},children:et})]})},n.title)}function me(n){const[a,r]=N.useState(!1),[o,i]=N.useState(n.options),l=y=>{n.onDragComplete(y),i(y)},E=y=>{const p=[...o];p.splice(y,1),l(p)},m=[];o.forEach((y,p)=>{m.push(u.jsx(be,{index:p,title:y,onDelete:E},y))});let d="dropdown draggable";return n.subdropdown&&(d+=" subdropdown"),u.jsxs("div",{className:d,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),children:[u.jsx(ee,{title:n.title}),u.jsx(le.Reorder.Group,{axis:"y",values:o,onReorder:l,style:{visibility:a?"visible":"hidden"},children:m})]})}function ge(n){const[a,r]=N.useState(!1),o=[];n.options.map((l,E)=>{n.onSelect!==void 0&&(l.onSelect=n.onSelect),o.push(u.jsx(Ee,{option:l},E))});let i="dropdown";return n.subdropdown&&(i+=" subdropdown"),u.jsxs("div",{className:i,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),children:[u.jsx(ee,{title:n.title}),u.jsx("ul",{style:{visibility:a?"visible":"hidden"},children:o})]})}function Ee(n){const{option:a}=n,[r,o]=N.useState("");let i=null;switch(a.type){case"draggable":i=u.jsx(me,{title:a.title,options:a.value,onDragComplete:l=>{a.onDragComplete!==void 0&&a.onDragComplete(l)},subdropdown:!0});break;case"dropdown":i=u.jsx(ge,{title:a.title,options:a.value,onSelect:a.onSelect,subdropdown:!0});break;case"option":i=u.jsx("button",{onClick:()=>{a.onSelect!==void 0&&a.onSelect(a.value),a.selectable&&(r!==a.title?o(a.title):o(""))},children:a.title});break}return u.jsx("li",{className:r===a.title?"selected":"",children:i},Je())}function rt(n){let a;const r=()=>{W.ui.hide(),n.listen(i=>{var E,m,d,y,p,S,_,F,H;let l;switch(i.event){case"draggableListUpdate":k.dispatchEvent({type:P.DRAG_UPDATE,value:i.data});break;case"selectComponent":k.dispatchEvent({type:P.SELECT_DROPDOWN,value:i.data});break;case"addFolder":(E=n.debug)==null||E.addFolder(i.data.name,i.data.params,i.data.parent);break;case"bindObject":(m=n.debug)==null||m.bind(i.data.name,i.data.params,i.data.parent);break;case"updateBind":(d=n.debug)==null||d.triggerBind(i.data.id,i.data.value);break;case"addButton":(y=n.debug)==null||y.button(i.data.name,i.data.callback,i.data.parent);break;case"clickButton":(p=n.debug)==null||p.triggerButton(i.data.id);break;case"setSheet":l=(S=n.theatre)==null?void 0:S.sheets.get(i.data.sheet),l!==void 0&&(a=l,W.setSelection([l]));break;case"setSheetObject":l=(_=n.theatre)==null?void 0:_.sheetObjects.get(`${i.data.sheet}_${i.data.key}`),l!==void 0&&W.setSelection([l]);break;case"updateSheetObject":l=(F=n.theatre)==null?void 0:F.sheetObjectCBs.get(i.data.sheetObject),l!==void 0&&l(i.data.values);break;case"updateTimeline":a=(H=n.theatre)==null?void 0:H.sheets.get(i.data.sheet),a!==void 0&&(a.sequence.position=i.data.position);break}})},o=()=>{W.ui.restore(),W.onSelectionChange(m=>{m.length<1||m.forEach(d=>{var _;let y=d.address.sheetId,p="setSheet",S={};switch(d.type){case"Theatre_Sheet_PublicAPI":p="setSheet",S={sheet:d.address.sheetId},a=(_=n.theatre)==null?void 0:_.sheets.get(d.address.sheetId);break;case"Theatre_SheetObject_PublicAPI":p="setSheetObject",y+=`_${d.address.objectKey}`,S={id:y,sheet:d.address.sheetId,key:d.address.objectKey};break}n.send({event:p,data:S})})});let i=0;const l=()=>{if(a!==void 0&&i!==a.sequence.position){i=a.sequence.position;const m=a;n.send({event:"updateTimeline",data:{position:i,sheet:m.address.sheetId}})}},E=()=>{l(),requestAnimationFrame(E)};l(),E()};n.editor?o():r()}const Ht="";function nt(n){if(n.name==="cameras")return"camera";if(n.name==="interactive")return"interactive";if(n.name==="lights")return"light";if(n.name==="ui")return"ui";if(n.name==="utils")return"utils";const a=n.type;return a.search("Helper")>-1?"icon_utils":a.search("Camera")>-1?"camera":a.search("Light")>-1?"light":"obj3D"}function ye(n){const[a,r]=N.useState(!1);let o=null,i=!1;if(n.child.children.length>0){i=!0;const l=[];n.child.children.map(E=>{l.push(u.jsx(ye,{child:E},Math.random()))}),o=u.jsx("div",{className:`container ${a?"":"closed"}`,children:l})}return u.jsxs("div",{className:"childObject",children:[u.jsxs("div",{className:"child",children:[i?u.jsx("button",{className:"status",style:{backgroundPositionX:a?"-14px":"2px"},onClick:()=>{r(!a)}}):null,u.jsx("button",{className:"name",style:{left:i?"20px":"5px"},onClick:()=>{k.dispatchEvent({type:P.INSPECT_ITEM,value:n.child})},children:n.child.name.length>0?`${n.child.name} (${n.child.type})`:`${n.child.type}::${n.child.uuid}`}),u.jsx("div",{className:`icon ${nt(n.child)}`})]}),o]},Math.random())}function at(n){const a=[];return n.child.children.map(r=>{a.push(u.jsx(ye,{child:r},Math.random()))}),u.jsx("div",{className:"scene",children:a})}class it extends N.Component{constructor(r){super(r);C(this,"onUpdate",()=>{});C(this,"toggleOpen",()=>{this.setState(()=>({open:!this.componentState.open}))});C(this,"onRefresh",()=>{k.dispatchEvent({type:P.INSPECT_ITEM,value:this.componentState.scene})});C(this,"onSetScene",r=>{console.log("SceneHierarchy::onSetScene",r),this.setState(()=>({scene:r.value}))});this.state={open:!1,scene:null},k.addEventListener(P.REFRESH_SCENE,this.onUpdate),k.addEventListener(P.SET_SCENE,this.onSetScene)}componentWillUnmount(){k.removeEventListener(P.REFRESH_SCENE,this.onUpdate),k.removeEventListener(P.SET_SCENE,this.onSetScene)}render(){const r=this.componentState.scene!==null?`Hierarchy: ${this.componentState.scene.name}`:"Hierarchy";return u.jsxs("div",{id:"SceneHierarchy",children:[u.jsxs("div",{className:"header",children:[u.jsx("button",{className:"status",style:{backgroundPositionX:this.componentState.open?"-14px":"2px"},onClick:this.toggleOpen}),u.jsx("span",{children:r}),u.jsx("button",{className:"refresh hideText",onClick:this.onRefresh,children:"Refresh"})]}),this.componentState.scene!==null&&this.componentState.open?u.jsx(at,{child:this.componentState.scene}):null]})}get componentState(){return this.state}}const Vt="";function st(n){return u.jsxs("div",{className:"editor",children:[u.jsx("div",{className:"navBar",children:n.children}),n.components]})}v.Application=Xe,v.BaseRemote=q,v.Draggable=me,v.DraggableItem=be,v.Dropdown=ge,v.DropdownItem=Ee,v.Editor=st,v.NavButton=ee,v.RemoteComponents=ue,v.RemoteController=rt,v.RemoteTheatre=fe,v.RemoteTweakpane=he,v.SceneHierarchy=it,v.ToolEvents=P,v.debugDispatcher=k,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
Binary file
Binary file
Binary file
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ #SceneHierarchy .header .refresh{background-color:transparent;background-image:url(/images/debug/icon_refresh.png);background-size:20px 20px;opacity:.7;transform:translateY(-50%) scale(.8)}#SceneHierarchy .status{background-image:url(/images/debug/icon_folder.png);background-position-x:2px;background-position-y:2px;background-size:32px 16px;transform:scale(.8);width:20px;height:20px}#SceneHierarchy .childObject .icon{background-color:transparent;background-image:url(/images/debug/icon_world.png);background-size:20px 20px;display:inline-block;position:absolute;right:5px;top:0;width:20px;height:20px;transform:scale(.8)}#SceneHierarchy .childObject .obj3D{background-image:url(/images/debug/icon_world.png)}#SceneHierarchy .childObject .camera{background-image:url(/images/debug/icon_camera.png)}#SceneHierarchy .childObject .interactive{background-image:url(/images/debug/icon_interactive.png)}#SceneHierarchy .childObject .light{background-image:url(/images/debug/icon_lights.png)}#SceneHierarchy .childObject .ui{background-image:url(/images/debug/icon_ui.png)}#SceneHierarchy .childObject .utils{background-image:url(/images/debug/icon_utils.png)}body .tp-dfwv,body .tp-dfwv button,body .tp-dfwv input{text-transform:none}.tp-ckbv{float:right}.tp-dfwv .tp-lblv{position:relative}.tp-dfwv .tp-lblv_v{display:inline-block;max-width:160px}.tp-dfwv .tp-lblv_v .tp-ckbv{width:20px}.tp-dfwv .tp-lblv_v .tp-txtv,.tp-dfwv .tp-lblv_v .tp-sldtxtv{max-width:160px}.tp-dfwv .tp-lblv_v .tp-lstv{width:160px}.tp-dfwv .tp-lblv_v .tp-fpsv,.tp-dfwv .tp-lblv-nol .tp-btnv{width:280px}.tp-dfwv .tp-btnv_b{padding:0 5px}.tp-dfwv .tp-btngridv{max-height:100px;overflow-x:hidden;overflow-y:auto}.tp-dfwv .tp-tabv{max-height:90vh;overflow:hidden auto}.tp-dfwv{font-family:Roboto Mono,Source Code Pro,Menlo,Courier,monospace;font-size:10px}#SceneHierarchy{background-color:#0d0d0d;border-radius:2px;bottom:0;right:0;font-family:Roboto Mono,Source Code Pro,Menlo,Courier,monospace;font-size:10px;min-height:20px;overflow:hidden;pointer-events:visible;position:absolute;width:250px;z-index:100}#SceneHierarchy button{background-color:transparent;border:none;color:#fff;font-size:12px;margin:0;padding:0;text-align:left}#SceneHierarchy .header{height:20px;position:relative}#SceneHierarchy .header span{display:inline-block;font-size:12px;line-height:20px;padding-left:20px;pointer-events:none}#SceneHierarchy .header button{position:absolute;right:5px;top:50%;width:20px;height:20px}#SceneHierarchy .header .refresh{background-color:transparent;background-image:url(/images/debug/icon_refresh.png);background-size:20px 20px;opacity:.7;transform:translateY(-50%) scale(.8)}#SceneHierarchy .header .refresh:hover{opacity:1}#SceneHierarchy .header .status{left:0;transform:translateY(-50%) scale(.8)}#SceneHierarchy .status{background-image:url(/images/debug/icon_folder.png);background-position-x:2px;background-position-y:2px;background-size:32px 16px;transform:scale(.8);width:20px;height:20px}#SceneHierarchy .childObject{background-color:#111;min-height:20px;overflow:hidden}#SceneHierarchy .childObject ::-webkit-scrollbar{width:10px}#SceneHierarchy .childObject ::-webkit-scrollbar-track{background:#0d0d0d}#SceneHierarchy .childObject ::-webkit-scrollbar-thumb{background:#666}#SceneHierarchy .childObject ::-webkit-scrollbar-thumb:hover{background:#999}#SceneHierarchy .childObject .child{background-color:#222;border:none;border-bottom:1px solid #111;height:20px;position:relative}#SceneHierarchy .childObject .child:hover{background-color:#333}#SceneHierarchy .childObject .name{background-color:transparent;max-lines:1;position:absolute;left:5px;right:0;top:50%;transform:translateY(-50%);white-space:nowrap}#SceneHierarchy .childObject .container{padding-left:5px;height:auto;overflow-x:hidden;overflow-y:auto;max-height:200px}#SceneHierarchy .childObject .container.closed{height:0;overflow:hidden}#SceneHierarchy .childObject .icon{background-color:transparent;background-image:url(/images/debug/icon_world.png);background-size:20px 20px;display:inline-block;position:absolute;right:5px;top:0;width:20px;height:20px;transform:scale(.8)}#SceneHierarchy .childObject .obj3D{background-image:url(/images/debug/icon_world.png)}#SceneHierarchy .childObject .camera{background-image:url(/images/debug/icon_camera.png)}#SceneHierarchy .childObject .interactive{background-image:url(/images/debug/icon_interactive.png)}#SceneHierarchy .childObject .light{background-image:url(/images/debug/icon_lights.png)}#SceneHierarchy .childObject .ui{background-image:url(/images/debug/icon_ui.png)}#SceneHierarchy .childObject .utils{background-image:url(/images/debug/icon_utils.png)}.editor{font-family:Helvetica,Arial,sans-serif;pointer-events:none;position:absolute;width:100%;height:100%;z-index:101}.editor button{background:none;border:none;color:#fff;display:inline-block;margin:0;padding:0;text-align:left}.editor .navBar{display:inline-block;pointer-events:visible;position:relative;left:50px;top:12px}.editor .dropdown{color:#fff;display:inline-block;margin-right:1px;text-align:left;height:fit-content;min-width:auto;width:max-content}.editor .dropdown button{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background-color:#222c;color:#ffffff80;font-size:12px;padding:5px 10px;position:relative;text-align:left;min-width:22px;width:100%;height:32px;transition:all .2s linear}.editor .dropdown button:hover{background-color:#333c;color:#fff}.editor .dropdown button.svg{line-height:0;width:32px}.editor .dropdown p{background-color:#222c;display:inline-block;height:22px;margin:0;min-width:22px;padding:5px}.editor .dropdown svg{position:relative;left:50%;transform:translate(-50%)}.editor .dropdown ul{list-style:none;margin:0;margin-block:0;padding-inline:0;position:absolute;width:max-content}.editor .dropdown ul li{border-top:1px solid rgba(17,17,17,.9);display:block;position:relative}.editor .dropdown ul li.selected button{background-color:#444c}.editor .dropdown ul li.selected button:hover{background-color:#555c}.editor .dropdown.subdropdown{min-width:100%}.editor .dropdown.subdropdown ul{border-left:1px solid rgba(17,17,17,.9);left:100%;top:-1px}.editor .draggable li div{background-color:#222c;line-height:14px;padding:5px 10px;transition:background-color .25s linear}.editor .draggable li div:hover{background-color:#333c}.editor .draggable li div span{font-size:12px;margin:0 15px 0 10px;padding:0 5px}.editor .draggable li div .dragIcon{position:absolute;left:10px}.editor .draggable li div .closeIcon{background-color:transparent;padding:0;position:absolute;right:5px;top:50%;min-width:14px;width:14px;height:14px;transform:translateY(-50%)}.editor .draggable li div .closeIcon:hover{background-color:transparent}.editor .draggable li div .closeIcon svg{background-color:transparent;left:0;position:relative}.fsAbsolute{position:absolute;left:0;right:0;top:0;bottom:0}.absoluteCenter{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}.hidden{display:none;visibility:hidden}.hideText{text-indent:-9999px;white-space:nowrap}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@tomorrowevening/hermes",
3
+ "author": "Colin Duffy <http://tomorrowevening.com/>",
4
+ "license": "GPL-3.0-or-later",
5
+ "version": "0.0.0",
6
+ "type": "module",
7
+ "files": [
8
+ "src/**/*.css",
9
+ "src/**/*.scss",
10
+ "src",
11
+ "dist",
12
+ "types/**/*.d.ts"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/tomorrowevening/hermes.git"
17
+ },
18
+ "scripts": {
19
+ "clean": "rm -r dist && rm -r types",
20
+ "dev": "vite",
21
+ "build": "tsc --declaration --emitDeclarationOnly --declarationDir types && vite build",
22
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
23
+ "preview": "vite preview"
24
+ },
25
+ "dependencies": {
26
+ "@theatre/core": "0.7.0",
27
+ "@tweakpane/plugin-essentials": "^0.2.0",
28
+ "framer-motion": "^10.16.0",
29
+ "react": "^18.2.0",
30
+ "react-dom": "^18.2.0",
31
+ "three": "^0.155.0",
32
+ "tweakpane": "^4.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "@theatre/studio": "0.7.0",
36
+ "@types/react": "^18.2.15",
37
+ "@types/react-dom": "^18.2.7",
38
+ "@types/three": "0.155.0",
39
+ "@typescript-eslint/eslint-plugin": "^6.4.0",
40
+ "@typescript-eslint/parser": "^6.4.0",
41
+ "@vitejs/plugin-react": "^4.0.3",
42
+ "eslint": "^8.45.0",
43
+ "eslint-plugin-react": "^7.33.2",
44
+ "eslint-plugin-react-hooks": "^4.6.0",
45
+ "eslint-plugin-react-refresh": "^0.4.3",
46
+ "path": "^0.12.7",
47
+ "sass": "^1.66.1",
48
+ "typescript": "^5.0.2",
49
+ "vite": "^4.4.5"
50
+ },
51
+ "description": "An extendable set of Web Tools controlled via a separate window for non-intereference with content.",
52
+ "bugs": {
53
+ "url": "https://github.com/tomorrowevening/hermes/issues"
54
+ },
55
+ "homepage": "https://github.com/tomorrowevening/hermes#readme",
56
+ "main": "index.js",
57
+ "keywords": [
58
+ "Editor",
59
+ "Remote",
60
+ "TheatreJS",
61
+ "Tweakpane"
62
+ ]
63
+ }
@@ -0,0 +1,69 @@
1
+ // Libs
2
+ import type { IProjectConfig } from '@theatre/core'
3
+ // Core
4
+ import RemoteComponents from './remote/RemoteComponents'
5
+ import RemoteTheatre from './remote/RemoteTheatre'
6
+ import RemoteTweakpane from './remote/RemoteTweakpane'
7
+ import type { ApplicationMode, BroadcastCallback, BroadcastData } from './types'
8
+
9
+ export default class Application {
10
+ components?: RemoteComponents
11
+ debug?: RemoteTweakpane
12
+ theatre?: RemoteTheatre
13
+
14
+ // Protected
15
+ protected mode: ApplicationMode = 'listener'
16
+ protected channel?: BroadcastChannel | undefined = undefined
17
+
18
+ constructor(debugEnabled: boolean, editorHashtag: string) {
19
+ this.editor = debugEnabled && document.location.hash.search(editorHashtag) > -1
20
+ if (debugEnabled) this.channel = new BroadcastChannel('theatre')
21
+ }
22
+
23
+ setupComponents() {
24
+ this.components = new RemoteComponents(this)
25
+ }
26
+
27
+ setupGUI() {
28
+ this.debug = new RemoteTweakpane(this)
29
+ }
30
+
31
+ setupTheatre(projectName: string, projectConfig?: IProjectConfig | undefined) {
32
+ this.theatre = new RemoteTheatre(this, projectName, projectConfig)
33
+ }
34
+
35
+ dispose() {
36
+ this.components?.dispose()
37
+ this.debug?.dispose()
38
+ this.theatre?.dispose()
39
+ }
40
+
41
+ // Remote
42
+
43
+ send(data: BroadcastData) {
44
+ if (this.mode === 'editor' && this.channel !== undefined) {
45
+ this.channel.postMessage(data)
46
+ }
47
+ }
48
+
49
+ listen(callback: BroadcastCallback) {
50
+ if (this.mode === 'listener' && this.channel !== undefined) {
51
+ this.channel.onmessage = (event: MessageEvent) => {
52
+ callback(event.data)
53
+ }
54
+ }
55
+ }
56
+
57
+ // Getters / Setters
58
+
59
+ get editor(): boolean {
60
+ return this.mode === 'editor'
61
+ }
62
+
63
+ set editor(value: boolean) {
64
+ if (value) {
65
+ this.mode = 'editor'
66
+ document.title += ' - Editor'
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,135 @@
1
+ // Libs
2
+ import type { ISheet } from '@theatre/core'
3
+ import studio from '@theatre/studio'
4
+ // Core
5
+ import Application from './Application'
6
+ import { ToolEvents, debugDispatcher } from '../editor/global'
7
+ import type { BroadcastData, EditorEvent } from './types'
8
+
9
+ export default function RemoteController(app: Application) {
10
+ let activeSheet: ISheet | undefined = undefined
11
+
12
+ // Application
13
+ const showApp = () => {
14
+ studio.ui.hide()
15
+
16
+ app.listen((msg: BroadcastData) => {
17
+ let value = undefined
18
+ switch (msg.event) {
19
+ // Components
20
+ case 'draggableListUpdate':
21
+ debugDispatcher.dispatchEvent({ type: ToolEvents.DRAG_UPDATE, value: msg.data })
22
+ break
23
+ case 'selectComponent':
24
+ debugDispatcher.dispatchEvent({ type: ToolEvents.SELECT_DROPDOWN, value: msg.data })
25
+ break
26
+
27
+ // GUI Events
28
+ case 'addFolder':
29
+ app.debug?.addFolder(msg.data.name, msg.data.params, msg.data.parent)
30
+ break
31
+ case 'bindObject':
32
+ app.debug?.bind(msg.data.name, msg.data.params, msg.data.parent)
33
+ break
34
+ case 'updateBind':
35
+ app.debug?.triggerBind(msg.data.id, msg.data.value)
36
+ break
37
+ case 'addButton':
38
+ app.debug?.button(msg.data.name, msg.data.callback, msg.data.parent)
39
+ break
40
+ case 'clickButton':
41
+ app.debug?.triggerButton(msg.data.id)
42
+ break
43
+
44
+ // Theatre Events
45
+ case 'setSheet':
46
+ value = app.theatre?.sheets.get(msg.data.sheet)
47
+ if (value !== undefined) {
48
+ activeSheet = value
49
+ studio.setSelection([value])
50
+ }
51
+ break
52
+ case 'setSheetObject':
53
+ value = app.theatre?.sheetObjects.get(`${msg.data.sheet}_${msg.data.key}`)
54
+ if (value !== undefined) {
55
+ studio.setSelection([value])
56
+ }
57
+ break
58
+ case 'updateSheetObject':
59
+ value = app.theatre?.sheetObjectCBs.get(msg.data.sheetObject)
60
+ if (value !== undefined) value(msg.data.values)
61
+ break
62
+ case 'updateTimeline':
63
+ activeSheet = app.theatre?.sheets.get(msg.data.sheet)
64
+ if (activeSheet !== undefined) {
65
+ activeSheet.sequence.position = msg.data.position
66
+ }
67
+ break
68
+ }
69
+ })
70
+ }
71
+
72
+ // Editor
73
+ const showEditor = () => {
74
+ studio.ui.restore()
75
+
76
+ studio.onSelectionChange((value: any[]) => {
77
+ if (value.length < 1) return
78
+
79
+ value.forEach((obj: any) => {
80
+ let id = obj.address.sheetId
81
+ let type: EditorEvent = 'setSheet'
82
+ let data = {}
83
+ switch (obj.type) {
84
+ case 'Theatre_Sheet_PublicAPI':
85
+ type = 'setSheet'
86
+ data = {
87
+ sheet: obj.address.sheetId,
88
+ }
89
+ activeSheet = app.theatre?.sheets.get(obj.address.sheetId)
90
+ break
91
+
92
+ case 'Theatre_SheetObject_PublicAPI':
93
+ type = 'setSheetObject'
94
+ id += `_${obj.address.objectKey}`
95
+ data = {
96
+ id: id,
97
+ sheet: obj.address.sheetId,
98
+ key: obj.address.objectKey,
99
+ }
100
+ break
101
+ }
102
+ app.send({ event: type, data: data })
103
+ })
104
+ })
105
+
106
+ // Timeline
107
+ let position = 0
108
+ const onRafUpdate = () => {
109
+ if (
110
+ activeSheet !== undefined &&
111
+ position !== activeSheet.sequence.position
112
+ ) {
113
+ position = activeSheet.sequence.position
114
+ const t = activeSheet as ISheet
115
+ app.send({
116
+ event: 'updateTimeline',
117
+ data: {
118
+ position: position,
119
+ sheet: t.address.sheetId,
120
+ },
121
+ })
122
+ }
123
+ }
124
+ const onRaf = () => {
125
+ onRafUpdate()
126
+ requestAnimationFrame(onRaf)
127
+ }
128
+ onRafUpdate() // Initial position
129
+ onRaf()
130
+
131
+
132
+ }
133
+
134
+ app.editor ? showEditor() : showApp()
135
+ }
@@ -0,0 +1,16 @@
1
+ import Application from '../Application'
2
+
3
+ /**
4
+ * Base class for remote-related extensions
5
+ */
6
+ export default class BaseRemote {
7
+ protected app: Application
8
+
9
+ constructor(app: Application) {
10
+ this.app = app
11
+ }
12
+
13
+ dispose() {
14
+ //
15
+ }
16
+ }
@@ -0,0 +1,32 @@
1
+ // Core
2
+ import Application from '../Application'
3
+ import BaseRemote from './BaseRemote'
4
+
5
+ /**
6
+ * Communicates between custom React Components
7
+ */
8
+ export default class RemoteComponents extends BaseRemote {
9
+ constructor(app: Application) {
10
+ super(app)
11
+ }
12
+
13
+ selectDropdown(dropdown: string, value: any) {
14
+ this.app.send({
15
+ event: 'selectComponent',
16
+ data: {
17
+ dropdown,
18
+ value
19
+ }
20
+ })
21
+ }
22
+
23
+ updateDropdown(dropdown: string, list: string[]) {
24
+ this.app.send({
25
+ event: 'draggableListUpdate',
26
+ data: {
27
+ dropdown,
28
+ value: list
29
+ }
30
+ })
31
+ }
32
+ }
@@ -0,0 +1,117 @@
1
+ // Libs
2
+ import { getProject } from '@theatre/core'
3
+ import type { IProject, IProjectConfig, ISheet, ISheetObject } from '@theatre/core'
4
+ // Core
5
+ import Application from '../Application'
6
+ import BaseRemote from './BaseRemote'
7
+ import { isColor } from '../../editor/utils'
8
+ import { noop } from '../types'
9
+ import type { DataUpdateCallback, VoidCallback } from '../types'
10
+
11
+ export default class RemoteTheatre extends BaseRemote {
12
+ project: IProject | undefined
13
+ sheets: Map<string, ISheet>
14
+ sheetObjects: Map<string, ISheetObject>
15
+ sheetObjectCBs: Map<string, DataUpdateCallback>
16
+ sheetObjectUnsubscribe: Map<string, VoidCallback>
17
+
18
+ constructor(app: Application, projectName: string, projectConfig?: IProjectConfig | undefined) {
19
+ super(app)
20
+ this.project = getProject(projectName, projectConfig)
21
+ this.sheets = new Map()
22
+ this.sheetObjects = new Map()
23
+ this.sheetObjectCBs = new Map()
24
+ this.sheetObjectUnsubscribe = new Map()
25
+ }
26
+
27
+ override dispose(): void {
28
+ this.project = undefined
29
+ this.sheets = new Map()
30
+ this.sheetObjects = new Map()
31
+ this.sheetObjectCBs = new Map()
32
+ this.sheetObjectUnsubscribe = new Map()
33
+ }
34
+
35
+ sheet(name: string): ISheet | undefined {
36
+ if (this.project === undefined) {
37
+ console.error('Theatre Project hasn\'t been created yet.')
38
+ return undefined
39
+ }
40
+
41
+ let sheet = this.sheets.get(name)
42
+ if (sheet !== undefined) return sheet
43
+
44
+ sheet = this.project?.sheet(name)
45
+ this.sheets.set(name, sheet)
46
+ return sheet
47
+ }
48
+
49
+ sheetObject(
50
+ sheetName: string,
51
+ key: string,
52
+ props: any,
53
+ onUpdate?: DataUpdateCallback,
54
+ ): ISheetObject | undefined {
55
+ if (this.project === undefined) {
56
+ console.error('Theatre Project hasn\'t been created yet.')
57
+ return undefined
58
+ }
59
+ const sheet = this.sheets.get(sheetName)
60
+ if (sheet === undefined) return undefined
61
+
62
+ const objName = `${sheetName}_${key}`
63
+ let obj = this.sheetObjects.get(objName)
64
+ if (obj !== undefined) {
65
+ obj = sheet.object(key, {...props, ...obj.value}, {reconfigure: true})
66
+ return obj
67
+ }
68
+
69
+ obj = sheet.object(key, props)
70
+ this.sheetObjects.set(objName, obj)
71
+ this.sheetObjectCBs.set(objName, onUpdate !== undefined ? onUpdate : noop)
72
+
73
+ const unsubscribe = obj.onValuesChange((values: any) => {
74
+ if (this.app.editor) {
75
+ for (const i in values) {
76
+ const value = values[i]
77
+ if (typeof value === 'object') {
78
+ if (isColor(value)) {
79
+ values[i] = {
80
+ r: value.r,
81
+ g: value.g,
82
+ b: value.b,
83
+ a: value.a,
84
+ }
85
+ }
86
+ }
87
+ }
88
+ this.app.send({
89
+ event: 'updateSheetObject',
90
+ data: {
91
+ sheetObject: objName,
92
+ values: values,
93
+ },
94
+ })
95
+ } else {
96
+ const callback = this.sheetObjectCBs.get(objName)
97
+ if (callback !== undefined) callback(values)
98
+ }
99
+ })
100
+ this.sheetObjectUnsubscribe.set(objName, unsubscribe)
101
+
102
+ return obj
103
+ }
104
+
105
+ unsubscribe(sheet: ISheetObject) {
106
+ if (this.project === undefined) {
107
+ console.error('Theatre Project hasn\'t been created yet.')
108
+ return undefined
109
+ }
110
+
111
+ const id = `${sheet.address.sheetId}_${sheet.address.objectKey}`
112
+ const unsubscribe = this.sheetObjectUnsubscribe.get(id)
113
+ if (unsubscribe !== undefined) {
114
+ unsubscribe()
115
+ }
116
+ }
117
+ }