@lovelace_lol/polymer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +226 -0
  2. package/dist/index.d.ts +2603 -0
  3. package/dist/index.js +1031 -0
  4. package/dist/test.cjs +1519 -0
  5. package/dist/worker/agency-worker.js +972 -0
  6. package/dist/worker/manifest.edn +1 -0
  7. package/package.json +57 -0
  8. package/shadow-cljs.edn +173 -0
  9. package/src/polymer/animation/agency.cljs +84 -0
  10. package/src/polymer/animation/domain.cljs +110 -0
  11. package/src/polymer/animation/planner.cljs +88 -0
  12. package/src/polymer/animation/runtime.cljs +137 -0
  13. package/src/polymer/animation/scheduler.cljs +178 -0
  14. package/src/polymer/animation/service.cljs +981 -0
  15. package/src/polymer/animation/state.cljs +112 -0
  16. package/src/polymer/blink/agency.cljs +131 -0
  17. package/src/polymer/blink/planner.cljs +115 -0
  18. package/src/polymer/blink/scheduler.cljs +90 -0
  19. package/src/polymer/blink/snippet.cljs +50 -0
  20. package/src/polymer/blink/state.cljs +102 -0
  21. package/src/polymer/camera_context/agency.cljs +132 -0
  22. package/src/polymer/camera_context/domain.cljs +186 -0
  23. package/src/polymer/camera_context/planner.cljs +50 -0
  24. package/src/polymer/camera_context/scheduler.cljs +113 -0
  25. package/src/polymer/camera_context/state.cljs +121 -0
  26. package/src/polymer/character.cljs +471 -0
  27. package/src/polymer/conversation/agency.cljs +83 -0
  28. package/src/polymer/conversation/domain.cljs +35 -0
  29. package/src/polymer/conversation/effector.cljs +130 -0
  30. package/src/polymer/conversation/planner.cljs +178 -0
  31. package/src/polymer/conversation/scheduler.cljs +202 -0
  32. package/src/polymer/conversation/service.cljs +329 -0
  33. package/src/polymer/conversation/state.cljs +186 -0
  34. package/src/polymer/core.cljs +172 -0
  35. package/src/polymer/eye_head/agency.cljs +75 -0
  36. package/src/polymer/eye_head/domain.cljs +133 -0
  37. package/src/polymer/eye_head/goap.cljs +106 -0
  38. package/src/polymer/eye_head/scheduler.cljs +176 -0
  39. package/src/polymer/eye_head/service.cljs +259 -0
  40. package/src/polymer/eye_head/snippet.cljs +92 -0
  41. package/src/polymer/eye_head/state.cljs +167 -0
  42. package/src/polymer/gaze/agency.cljs +85 -0
  43. package/src/polymer/gaze/domain.cljs +211 -0
  44. package/src/polymer/gaze/goap.cljs +208 -0
  45. package/src/polymer/gaze/scheduler.cljs +184 -0
  46. package/src/polymer/gaze/state.cljs +202 -0
  47. package/src/polymer/gesture/agency.cljs +185 -0
  48. package/src/polymer/gesture/goap.cljs +461 -0
  49. package/src/polymer/gesture/scheduler.cljs +122 -0
  50. package/src/polymer/gesture/snippet.cljs +198 -0
  51. package/src/polymer/gesture/state.cljs +273 -0
  52. package/src/polymer/lipsync/agency.cljs +593 -0
  53. package/src/polymer/lipsync/articulation/jaw.cljs +258 -0
  54. package/src/polymer/lipsync/articulation/snippet.cljs +605 -0
  55. package/src/polymer/lipsync/articulation/tongue.cljs +418 -0
  56. package/src/polymer/lipsync/articulation/visemes.cljs +429 -0
  57. package/src/polymer/lipsync/goap.cljs +132 -0
  58. package/src/polymer/lipsync/pronunciation/effector.cljs +51 -0
  59. package/src/polymer/lipsync/scheduler.cljs +302 -0
  60. package/src/polymer/lipsync/state.cljs +202 -0
  61. package/src/polymer/nlp/phonemes.cljs +164 -0
  62. package/src/polymer/prosodic/agency.cljs +196 -0
  63. package/src/polymer/prosodic/goap.cljs +122 -0
  64. package/src/polymer/prosodic/scheduler.cljs +99 -0
  65. package/src/polymer/prosodic/snippet.cljs +106 -0
  66. package/src/polymer/prosodic/state.cljs +139 -0
  67. package/src/polymer/runtime/embody.cljs +117 -0
  68. package/src/polymer/runtime/embody_wasm.cljs +177 -0
  69. package/src/polymer/runtime/rust_embody_host.cljs +645 -0
  70. package/src/polymer/society.cljs +239 -0
  71. package/src/polymer/stream.cljs +130 -0
  72. package/src/polymer/transcription/agency.cljs +69 -0
  73. package/src/polymer/transcription/domain.cljs +68 -0
  74. package/src/polymer/transcription/effector.cljs +611 -0
  75. package/src/polymer/transcription/planner.cljs +203 -0
  76. package/src/polymer/transcription/scheduler.cljs +225 -0
  77. package/src/polymer/transcription/service.cljs +209 -0
  78. package/src/polymer/transcription/state.cljs +239 -0
  79. package/src/polymer/tts/agency.cljs +503 -0
  80. package/src/polymer/tts/azure.cljs +290 -0
  81. package/src/polymer/tts/planner.cljs +178 -0
  82. package/src/polymer/tts/runtime.cljs +624 -0
  83. package/src/polymer/tts/scheduler.cljs +162 -0
  84. package/src/polymer/tts/state.cljs +191 -0
  85. package/src/polymer/worker.cljs +70 -0
@@ -0,0 +1,137 @@
1
+ (ns polymer.animation.runtime
2
+ (:require [polymer.animation.domain :as domain]))
3
+
4
+ ;; Runtime functions are Animation's side-effect boundary. Everything here is
5
+ ;; allowed to touch JavaScript handles or an injected animation engine; planner,
6
+ ;; scheduler decision logic, and domain transforms are not.
7
+
8
+ (defn js-callable? [value]
9
+ (= "function" (goog/typeOf value)))
10
+
11
+ (defn js-method [target name]
12
+ (when target
13
+ (let [method (aget target name)]
14
+ (when (js-callable? method)
15
+ method))))
16
+
17
+ (defn call-js [target name & args]
18
+ (when-let [method (js-method target name)]
19
+ (.apply method target (to-array args))))
20
+
21
+ (defn play-built-handle! [handle]
22
+ (when-let [play (js-method handle "play")]
23
+ (.call play handle))
24
+ handle)
25
+
26
+ (defn engine->runtime [engine]
27
+ ;; Some callers still pass a larger engine object. Animation adapts it once
28
+ ;; into the smaller runtime API it needs, keeping that dependency at this
29
+ ;; boundary instead of leaking engine calls into other agencies.
30
+ (let [runtime #js {:buildClip (fn [clip-name curves options]
31
+ (call-js engine "buildClip" clip-name curves options))
32
+ :playSnippet (fn [clip-name curves options]
33
+ (or
34
+ (call-js engine "playSnippet" #js {:name clip-name :curves curves} options)
35
+ (let [handle (call-js engine "buildClip" clip-name curves options)]
36
+ (play-built-handle! handle))))
37
+ :updateClipParams (fn [clip-name params]
38
+ (call-js engine "updateClipParams" clip-name params))
39
+ :setSnippetTime (fn [clip-name offset-sec]
40
+ (or (call-js engine "setSnippetTime" clip-name offset-sec)
41
+ (call-js engine "seekSnippet" clip-name offset-sec)
42
+ (call-js engine "seek" clip-name offset-sec)))
43
+ :cleanupSnippet (fn [clip-name]
44
+ (or (call-js engine "cleanupSnippet" clip-name)
45
+ (call-js engine "stopAnimation" clip-name)))
46
+ :getAnimationState (fn [clip-name]
47
+ (call-js engine "getAnimationState" clip-name))}]
48
+ (when (js-method engine "buildTypedClip")
49
+ (aset runtime "buildTypedClip"
50
+ (fn [clip-name channels options]
51
+ (call-js engine "buildTypedClip" clip-name channels options))))
52
+ (when (or (js-method engine "playTypedSnippet")
53
+ (js-method engine "buildTypedClip"))
54
+ (aset runtime "playTypedSnippet"
55
+ (fn [snippet options]
56
+ (let [clip-name (aget snippet "name")
57
+ channels (aget snippet "channels")]
58
+ (or
59
+ (call-js engine "playTypedSnippet" snippet options)
60
+ (play-built-handle!
61
+ (call-js engine "buildTypedClip" clip-name channels options)))))))
62
+ runtime))
63
+
64
+ (defn config->runtime [config]
65
+ (let [config (or config #js {})
66
+ runtime (aget config "runtime")
67
+ engine (aget config "engine")]
68
+ (cond
69
+ runtime runtime
70
+ engine (engine->runtime engine)
71
+ :else nil)))
72
+
73
+ (defn typed-snippet-js [name channels]
74
+ (clj->js {:name name :channels channels}))
75
+
76
+ (defn play-typed-snippet! [runtime snippet options]
77
+ (let [name (:name snippet)
78
+ channels (domain/typed-channels snippet)
79
+ channels-js (clj->js channels)
80
+ clip-options (domain/snippet->clip-options snippet options)
81
+ snippet-js (typed-snippet-js name channels)]
82
+ (if (false? (:autoPlay options))
83
+ (or (call-js runtime "buildTypedClip" name channels-js clip-options)
84
+ (call-js runtime "playTypedSnippet" snippet-js clip-options))
85
+ (or (call-js runtime "playTypedSnippet" snippet-js clip-options)
86
+ (play-built-handle!
87
+ (call-js runtime "buildTypedClip" name channels-js clip-options))))))
88
+
89
+ (defn play-legacy-snippet! [runtime snippet options]
90
+ (when-let [curves (:curves snippet)]
91
+ (let [name (:name snippet)
92
+ curves-js (clj->js curves)
93
+ clip-options (domain/snippet->legacy-clip-options snippet options)]
94
+ (if (false? (:autoPlay options))
95
+ (or (call-js runtime "buildClip" name curves-js clip-options)
96
+ (call-js runtime "playSnippet" name curves-js clip-options))
97
+ (call-js runtime "playSnippet" name curves-js clip-options)))))
98
+
99
+ (defn play-snippet! [runtime snippet options]
100
+ ;; Typed snippets are Polymer's canonical animation contract. Legacy curve
101
+ ;; playback is only a compatibility path for runtimes that have not adopted
102
+ ;; typed channels yet.
103
+ (if (domain/typed-channels snippet)
104
+ (if (or (js-method runtime "playTypedSnippet")
105
+ (js-method runtime "buildTypedClip"))
106
+ (play-typed-snippet! runtime snippet options)
107
+ (when (seq (:curves snippet))
108
+ (play-legacy-snippet! runtime snippet options)))
109
+ (play-legacy-snippet! runtime snippet options)))
110
+
111
+ (defn cleanup-snippet! [runtime handle name]
112
+ (when-let [stop (js-method handle "stop")]
113
+ (.call stop handle))
114
+ (when runtime
115
+ (call-js runtime "cleanupSnippet" name)))
116
+
117
+ (defn seek-snippet! [runtime handle name offset-sec]
118
+ (let [normalized-offset (max 0 (or offset-sec 0))]
119
+ (or (when handle
120
+ (or (call-js handle "setTime" normalized-offset)
121
+ (call-js handle "seek" normalized-offset)))
122
+ (when runtime
123
+ (or (call-js runtime "setSnippetTime" name normalized-offset)
124
+ (call-js runtime "seekSnippet" name normalized-offset)
125
+ (call-js runtime "seek" name normalized-offset)
126
+ (call-js runtime "updateClipParams"
127
+ name
128
+ (clj->js {:time normalized-offset
129
+ :offsetSec normalized-offset})))))))
130
+
131
+ (defn update-snippet! [runtime handle name params]
132
+ (let [params-js (clj->js params)]
133
+ (or (when handle
134
+ (or (call-js handle "updateParams" params-js)
135
+ (call-js handle "setParams" params-js)))
136
+ (when runtime
137
+ (call-js runtime "updateClipParams" name params-js)))))
@@ -0,0 +1,178 @@
1
+ (ns polymer.animation.scheduler
2
+ (:require [polymer.animation.domain :as domain]
3
+ [polymer.animation.runtime :as runtime]
4
+ [polymer.animation.state :as state]))
5
+
6
+ ;; The scheduler owns Animation's ordered work queue and runtime handle
7
+ ;; lifecycle. Other agencies request animation as plain data; only this
8
+ ;; scheduler decides when to schedule, replace, cancel, seek, or update a
9
+ ;; runtime clip.
10
+
11
+ (def default-cleanup-buffer-ms 50)
12
+
13
+ (defn create-scheduler [{:keys [runtime state-atom emit-event disposed? debug-log! cleanup-buffer-ms]
14
+ :or {cleanup-buffer-ms default-cleanup-buffer-ms
15
+ debug-log! (fn [_label _payload] nil)}}]
16
+ (let [cleanup-timers (atom {})
17
+ handles (atom {})
18
+ generation (atom 0)
19
+ queue (atom [])
20
+ draining? (atom false)]
21
+ (letfn [(next-token! []
22
+ (swap! generation inc))
23
+
24
+ (handle-for [name]
25
+ (:handle (get @handles name)))
26
+
27
+ (current-token? [name token]
28
+ (= token (:token (get @handles name))))
29
+
30
+ (clear-cleanup! [name]
31
+ (when-let [entry (get @cleanup-timers name)]
32
+ (js/clearTimeout (:timer entry))
33
+ (swap! cleanup-timers dissoc name)))
34
+
35
+ (clear-all-cleanups! []
36
+ (doseq [[_ entry] @cleanup-timers]
37
+ (js/clearTimeout (:timer entry)))
38
+ (reset! cleanup-timers {}))
39
+
40
+ (emit-error! [message]
41
+ (emit-event {:type "error"
42
+ :agency "animation"
43
+ :message message}))
44
+
45
+ (cleanup-runtime! [name]
46
+ (let [handle (handle-for name)]
47
+ (runtime/cleanup-snippet! runtime handle name))
48
+ (swap! handles dissoc name))
49
+
50
+ (emit-remove! [name source-agency reason]
51
+ (when (and (not @disposed?)
52
+ (get-in @state-atom [:scheduled name]))
53
+ (clear-cleanup! name)
54
+ (cleanup-runtime! name)
55
+ (let [removed-at (state/now-ms)]
56
+ (swap! state-atom state/record-remove name source-agency removed-at reason)
57
+ (emit-event {:type "animationSnippetRemoved"
58
+ :agency "animation"
59
+ :sourceAgency source-agency
60
+ :reason reason
61
+ :name name
62
+ :removedAt removed-at}))))
63
+
64
+ (emit-remove-if-current! [name source-agency reason token]
65
+ ;; Runtime handles may resolve after a replacement. The token
66
+ ;; prevents an old completion callback from removing the newer
67
+ ;; snippet that reused the same name.
68
+ (when (current-token? name token)
69
+ (emit-remove! name source-agency reason)))
70
+
71
+ (schedule-cleanup! [name snippet source-agency handle token]
72
+ (clear-cleanup! name)
73
+ (when-let [finished (aget handle "finished")]
74
+ (when (runtime/js-callable? (aget finished "then"))
75
+ (.then finished
76
+ #(emit-remove-if-current! name source-agency "completed" token)
77
+ (fn [_error] nil))))
78
+ (when (not (:loop snippet))
79
+ (when-let [duration-ms (state/snippet-duration-ms snippet)]
80
+ (when (pos? duration-ms)
81
+ (let [timer (js/setTimeout
82
+ #(emit-remove-if-current! name source-agency "completed" token)
83
+ (+ duration-ms cleanup-buffer-ms))]
84
+ (swap! cleanup-timers assoc name {:timer timer
85
+ :token token}))))))
86
+
87
+ (schedule-snippet! [{:keys [sourceAgency requestedAt snippet options]}]
88
+ (let [name (:name snippet)
89
+ token (next-token!)]
90
+ (when (get-in @state-atom [:scheduled name])
91
+ (emit-remove! name sourceAgency "replaced"))
92
+ (debug-log! "[Polymer Animation CLJS] scheduleSnippet"
93
+ (domain/schedule-log-payload snippet options sourceAgency))
94
+ (swap! state-atom state/record-schedule snippet options sourceAgency requestedAt)
95
+ (emit-event {:type "animationSnippetScheduled"
96
+ :agency "animation"
97
+ :sourceAgency sourceAgency
98
+ :name name
99
+ :snippet snippet
100
+ :options options
101
+ :requestedAt requestedAt})
102
+ (if runtime
103
+ (if-let [handle (runtime/play-snippet! runtime snippet options)]
104
+ (do
105
+ (swap! handles assoc name {:handle handle
106
+ :token token})
107
+ (swap! state-atom state/record-start name sourceAgency (state/now-ms))
108
+ (emit-event {:type "animationSnippetStarted"
109
+ :agency "animation"
110
+ :sourceAgency sourceAgency
111
+ :name name})
112
+ (schedule-cleanup! name snippet sourceAgency handle token))
113
+ (emit-error! (str "Animation runtime did not return a clip handle for " name)))
114
+ (emit-error! "Animation agency requires an animation runtime or engine"))
115
+ snippet))
116
+
117
+ (seek-snippet! [{:keys [sourceAgency name offsetSec]}]
118
+ (if (runtime/seek-snippet! runtime (handle-for name) name offsetSec)
119
+ (let [seeked-at (state/now-ms)]
120
+ (swap! state-atom state/record-seek name sourceAgency seeked-at offsetSec)
121
+ (emit-event {:type "animationSnippetSeeked"
122
+ :agency "animation"
123
+ :sourceAgency sourceAgency
124
+ :name name
125
+ :offsetSec offsetSec
126
+ :seekedAt seeked-at}))
127
+ (emit-error! (str "Animation runtime could not seek " name))))
128
+
129
+ (update-snippet! [{:keys [sourceAgency name params]}]
130
+ (if (runtime/update-snippet! runtime (handle-for name) name params)
131
+ (let [updated-at (state/now-ms)]
132
+ (swap! state-atom state/record-update name sourceAgency updated-at params)
133
+ (emit-event {:type "animationSnippetUpdated"
134
+ :agency "animation"
135
+ :sourceAgency sourceAgency
136
+ :name name
137
+ :params params
138
+ :updatedAt updated-at}))
139
+ (emit-error! (str "Animation runtime could not update " name))))
140
+
141
+ (clear! [{:keys [sourceAgency names]}]
142
+ (doseq [name names]
143
+ (emit-remove! name sourceAgency "clear"))
144
+ (clear-all-cleanups!))
145
+
146
+ (run-action! [action]
147
+ (case (:op action)
148
+ :schedule (schedule-snippet! action)
149
+ :remove (emit-remove! (:name action) (:sourceAgency action) (:reason action))
150
+ :seek (seek-snippet! action)
151
+ :update (update-snippet! action)
152
+ :clear (clear! action)
153
+ :error (emit-error! (:message action))
154
+ (emit-error! (str "Unknown Animation scheduler action: " (:op action)))))
155
+
156
+ (drain! []
157
+ (when-not @draining?
158
+ (reset! draining? true)
159
+ (try
160
+ (loop []
161
+ (when-let [action (first @queue)]
162
+ (swap! queue #(vec (rest %)))
163
+ (run-action! action)
164
+ (recur)))
165
+ (finally
166
+ (reset! draining? false)))))
167
+
168
+ (enqueue-actions! [actions]
169
+ (swap! queue into actions)
170
+ (drain!))
171
+
172
+ (dispose! []
173
+ (doseq [name (keys @handles)]
174
+ (cleanup-runtime! name))
175
+ (clear-all-cleanups!)
176
+ (reset! queue []))]
177
+ {:enqueue-actions! enqueue-actions!
178
+ :dispose! dispose!})))