@lovelace_lol/polymer 0.0.7 → 0.0.9

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 (95) hide show
  1. package/README.md +434 -12
  2. package/dist/index.d.ts +1945 -244
  3. package/dist/index.js +1686 -1017
  4. package/dist/vision/face-worker.js +296 -0
  5. package/dist/vision/face_landmarker.task +0 -0
  6. package/dist/vision/manifest.edn +1 -0
  7. package/dist/vision/vision_bundle.js +2 -0
  8. package/dist/vision/wasm/vision_wasm_internal.js +8841 -0
  9. package/dist/vision/wasm/vision_wasm_internal.wasm +0 -0
  10. package/dist/vision/wasm/vision_wasm_module_internal.js +8837 -0
  11. package/dist/vision/wasm/vision_wasm_module_internal.wasm +0 -0
  12. package/dist/vision/wasm/vision_wasm_nosimd_internal.js +8832 -0
  13. package/dist/vision/wasm/vision_wasm_nosimd_internal.wasm +0 -0
  14. package/dist/worker/agency-worker.js +1276 -962
  15. package/dist/worker/manifest.edn +1 -1
  16. package/package.json +33 -20
  17. package/dist/test.cjs +0 -1519
  18. package/shadow-cljs.edn +0 -173
  19. package/src/polymer/animation/agency.cljs +0 -84
  20. package/src/polymer/animation/domain.cljs +0 -110
  21. package/src/polymer/animation/planner.cljs +0 -88
  22. package/src/polymer/animation/runtime.cljs +0 -137
  23. package/src/polymer/animation/scheduler.cljs +0 -178
  24. package/src/polymer/animation/service.cljs +0 -981
  25. package/src/polymer/animation/state.cljs +0 -112
  26. package/src/polymer/blink/agency.cljs +0 -131
  27. package/src/polymer/blink/planner.cljs +0 -115
  28. package/src/polymer/blink/scheduler.cljs +0 -90
  29. package/src/polymer/blink/snippet.cljs +0 -50
  30. package/src/polymer/blink/state.cljs +0 -102
  31. package/src/polymer/camera_context/agency.cljs +0 -132
  32. package/src/polymer/camera_context/domain.cljs +0 -186
  33. package/src/polymer/camera_context/planner.cljs +0 -50
  34. package/src/polymer/camera_context/scheduler.cljs +0 -113
  35. package/src/polymer/camera_context/state.cljs +0 -121
  36. package/src/polymer/character.cljs +0 -403
  37. package/src/polymer/conversation/agency.cljs +0 -83
  38. package/src/polymer/conversation/domain.cljs +0 -35
  39. package/src/polymer/conversation/effector.cljs +0 -130
  40. package/src/polymer/conversation/planner.cljs +0 -178
  41. package/src/polymer/conversation/scheduler.cljs +0 -202
  42. package/src/polymer/conversation/service.cljs +0 -329
  43. package/src/polymer/conversation/state.cljs +0 -186
  44. package/src/polymer/core.cljs +0 -172
  45. package/src/polymer/eye_head/agency.cljs +0 -75
  46. package/src/polymer/eye_head/domain.cljs +0 -133
  47. package/src/polymer/eye_head/goap.cljs +0 -106
  48. package/src/polymer/eye_head/scheduler.cljs +0 -176
  49. package/src/polymer/eye_head/service.cljs +0 -259
  50. package/src/polymer/eye_head/snippet.cljs +0 -92
  51. package/src/polymer/eye_head/state.cljs +0 -167
  52. package/src/polymer/gaze/agency.cljs +0 -85
  53. package/src/polymer/gaze/domain.cljs +0 -211
  54. package/src/polymer/gaze/goap.cljs +0 -208
  55. package/src/polymer/gaze/scheduler.cljs +0 -184
  56. package/src/polymer/gaze/state.cljs +0 -202
  57. package/src/polymer/gesture/agency.cljs +0 -185
  58. package/src/polymer/gesture/goap.cljs +0 -461
  59. package/src/polymer/gesture/scheduler.cljs +0 -122
  60. package/src/polymer/gesture/snippet.cljs +0 -198
  61. package/src/polymer/gesture/state.cljs +0 -273
  62. package/src/polymer/lipsync/agency.cljs +0 -593
  63. package/src/polymer/lipsync/articulation/jaw.cljs +0 -258
  64. package/src/polymer/lipsync/articulation/snippet.cljs +0 -605
  65. package/src/polymer/lipsync/articulation/tongue.cljs +0 -418
  66. package/src/polymer/lipsync/articulation/visemes.cljs +0 -429
  67. package/src/polymer/lipsync/goap.cljs +0 -132
  68. package/src/polymer/lipsync/pronunciation/effector.cljs +0 -51
  69. package/src/polymer/lipsync/scheduler.cljs +0 -302
  70. package/src/polymer/lipsync/state.cljs +0 -202
  71. package/src/polymer/nlp/phonemes.cljs +0 -164
  72. package/src/polymer/prosodic/agency.cljs +0 -196
  73. package/src/polymer/prosodic/goap.cljs +0 -122
  74. package/src/polymer/prosodic/scheduler.cljs +0 -99
  75. package/src/polymer/prosodic/snippet.cljs +0 -106
  76. package/src/polymer/prosodic/state.cljs +0 -139
  77. package/src/polymer/runtime/embody.cljs +0 -117
  78. package/src/polymer/runtime/embody_wasm.cljs +0 -177
  79. package/src/polymer/runtime/rust_embody_host.cljs +0 -647
  80. package/src/polymer/society.cljs +0 -253
  81. package/src/polymer/stream.cljs +0 -130
  82. package/src/polymer/transcription/agency.cljs +0 -69
  83. package/src/polymer/transcription/domain.cljs +0 -68
  84. package/src/polymer/transcription/effector.cljs +0 -611
  85. package/src/polymer/transcription/planner.cljs +0 -203
  86. package/src/polymer/transcription/scheduler.cljs +0 -225
  87. package/src/polymer/transcription/service.cljs +0 -209
  88. package/src/polymer/transcription/state.cljs +0 -239
  89. package/src/polymer/tts/agency.cljs +0 -503
  90. package/src/polymer/tts/azure.cljs +0 -290
  91. package/src/polymer/tts/planner.cljs +0 -178
  92. package/src/polymer/tts/runtime.cljs +0 -624
  93. package/src/polymer/tts/scheduler.cljs +0 -162
  94. package/src/polymer/tts/state.cljs +0 -191
  95. package/src/polymer/worker.cljs +0 -81
@@ -1,75 +0,0 @@
1
- (ns polymer.eye-head.agency
2
- (:require [polymer.eye-head.domain :as domain]
3
- [polymer.eye-head.goap :as goap]
4
- [polymer.eye-head.scheduler :as scheduler]
5
- [polymer.eye-head.state :as state]
6
- [polymer.stream :as stream]))
7
-
8
- ;; Eye/Head owns synchronized gaze movement. Peer agencies publish look
9
- ;; requests; this agency plans and schedules eye/head AU snippets for Animation.
10
-
11
- (defn now-ms
12
- []
13
- (.now js/Date))
14
-
15
- (defn create-eye-head-tracking-agency
16
- [config]
17
- (let [input-stream (stream/create-stream)
18
- event-stream (stream/create-stream)
19
- state-atom (atom (state/config->state config))
20
- disposed? (atom false)
21
- emit-input (:emit input-stream)
22
- emit-event (:emit event-stream)
23
- scheduler-atom (atom nil)]
24
- (letfn [(dispatch! [command]
25
- (when-not @disposed?
26
- (let [payload (domain/data-map command)
27
- plan (goap/plan-command payload @state-atom (now-ms))]
28
- (emit-input {:type "command"
29
- :agency "eyeHeadTracking"
30
- :command payload})
31
- (when-let [agency-scheduler @scheduler-atom]
32
- ((:schedule agency-scheduler) plan)))))
33
-
34
- (dispatch-type! [type]
35
- (dispatch! #js {:type type}))]
36
- (let [agency-scheduler (scheduler/create-scheduler
37
- {:state-atom state-atom
38
- :emit-event emit-event})]
39
- (reset! scheduler-atom agency-scheduler)
40
- #js {:dispatch dispatch!
41
- :snapshot (fn [] (state/visible-state @state-atom))
42
- :input (stream/writable-port input-stream dispatch!)
43
- :events (stream/readable-port event-stream)
44
- :subscribeInput (fn [listener] ((:subscribe input-stream) listener))
45
- :subscribeEvents (fn [listener] ((:subscribe event-stream) listener))
46
- :subscribe (fn [listener] ((:subscribe event-stream) listener))
47
- :subscribeStatus (fn [listener] ((:subscribe event-stream) listener))
48
- :setTarget (fn [target]
49
- (dispatch! #js {:type "setTarget"
50
- :target target}))
51
- :configure (fn [config]
52
- (dispatch! #js {:type "configure"
53
- :config config}))
54
- :enable (fn [] (dispatch-type! "enable"))
55
- :disable (fn [] (dispatch-type! "disable"))
56
- :reset (fn
57
- ([] (dispatch-type! "reset"))
58
- ([duration-ms] (dispatch! #js {:type "reset"
59
- :durationMs duration-ms})))
60
- :cancel (fn
61
- ([] (dispatch-type! "cancel"))
62
- ([reason] (dispatch! #js {:type "cancel"
63
- :reason reason})))
64
- :flush (fn []
65
- (when-let [agency-scheduler @scheduler-atom]
66
- ((:flush agency-scheduler))))
67
- :queue (fn []
68
- (when-let [agency-scheduler @scheduler-atom]
69
- (clj->js ((:queue agency-scheduler)))))
70
- :dispose (fn []
71
- (when-not @disposed?
72
- (reset! disposed? true)
73
- ((:dispose agency-scheduler))
74
- ((:dispose input-stream))
75
- ((:dispose event-stream))))}))))
@@ -1,133 +0,0 @@
1
- (ns polymer.eye-head.domain)
2
-
3
- ;; Eye/Head domain code normalizes incoming gaze requests and configuration.
4
- ;; It stays pure so movement policy can be tested without any animation runtime.
5
-
6
- (def zero-target {:x 0 :y 0 :z 0})
7
-
8
- (defn finite-number?
9
- [value]
10
- (and (number? value) (js/isFinite value)))
11
-
12
- (defn number-or
13
- [value fallback]
14
- (if (finite-number? value) value fallback))
15
-
16
- (defn clamp
17
- [lo hi value]
18
- (min hi (max lo value)))
19
-
20
- (defn data-map
21
- [value]
22
- (cond
23
- (map? value) value
24
- value (js->clj value :keywordize-keys true)
25
- :else {}))
26
-
27
- (defn normalize-target
28
- ([value] (normalize-target value zero-target))
29
- ([value fallback]
30
- (let [input (data-map value)
31
- fallback (merge zero-target fallback)]
32
- {:x (clamp -1 1 (number-or (:x input) (:x fallback)))
33
- :y (clamp -1 1 (number-or (:y input) (:y fallback)))
34
- :z (number-or (:z input) (:z fallback))})))
35
-
36
- (defn request-id
37
- [prefix now-ms]
38
- (str prefix ":" now-ms ":" (rand-int 1000000)))
39
-
40
- (defn requested-target
41
- [command]
42
- (let [payload (data-map command)]
43
- (or (:target payload)
44
- (:gazeTarget payload)
45
- (:lookTarget payload)
46
- (:value payload))))
47
-
48
- (defn has-requested-target?
49
- [command]
50
- (some? (requested-target command)))
51
-
52
- (defn request-source
53
- [command]
54
- (let [payload (data-map command)]
55
- (or (:source payload)
56
- (:agency payload)
57
- "gaze")))
58
-
59
- (defn normalize-gaze-request
60
- [command state now-ms]
61
- (let [payload (data-map command)
62
- config (:config state)
63
- target (normalize-target (requested-target payload))
64
- eye-enabled (if (contains? payload :eyeEnabled)
65
- (boolean (:eyeEnabled payload))
66
- true)
67
- head-enabled (if (contains? payload :headEnabled)
68
- (boolean (:headEnabled payload))
69
- true)
70
- head-follow-eyes (if (contains? payload :headFollowEyes)
71
- (boolean (:headFollowEyes payload))
72
- (:headFollowEyes config))]
73
- {:type "eyeHeadTracking.requestGaze"
74
- :agency "eyeHeadTracking"
75
- :sourceAgency (request-source payload)
76
- :requestId (or (:requestId payload) (request-id "eyeHeadTracking" now-ms))
77
- :target target
78
- :rawTarget (normalize-target (:rawTarget payload) target)
79
- :mode (or (:mode payload) (:mode state) "manual")
80
- :eyeEnabled (and (:eyeTrackingEnabled config) eye-enabled)
81
- :headEnabled (and (:headTrackingEnabled config) head-enabled)
82
- :headFollowEyes head-follow-eyes
83
- :eyeIntensity (number-or (:eyeIntensity payload) (:eyeIntensity config))
84
- :headIntensity (number-or (:headIntensity payload) (:headIntensity config))
85
- :headRoll (number-or (:headRoll payload) (:headRoll config))
86
- :eyeDurationMs (number-or (:eyeDurationMs payload)
87
- (:transitionDurationMs config))
88
- :headDurationMs (number-or (:headDurationMs payload)
89
- (:transitionDurationMs config))
90
- :createdAt (or (:createdAt payload) now-ms)}))
91
-
92
- (defn movement-enabled?
93
- [request]
94
- (or (:eyeEnabled request)
95
- (and (:headEnabled request) (:headFollowEyes request))))
96
-
97
- (defn normalize-reset-request
98
- [command state now-ms]
99
- (let [payload (data-map command)
100
- config (:config state)
101
- duration (number-or (:durationMs payload)
102
- (number-or (:duration-ms payload)
103
- (:returnToCenterDurationMs config)))]
104
- {:type "eyeHeadTracking.requestReset"
105
- :agency "eyeHeadTracking"
106
- :sourceAgency (request-source payload)
107
- :requestId (or (:requestId payload) (request-id "eyeHeadTracking:reset" now-ms))
108
- :target zero-target
109
- :rawTarget zero-target
110
- :mode (:mode state)
111
- :eyeEnabled (if (contains? payload :eyes)
112
- (and (:eyeTrackingEnabled config) (boolean (:eyes payload)))
113
- (:eyeTrackingEnabled config))
114
- :headEnabled (if (contains? payload :head)
115
- (and (:headTrackingEnabled config) (boolean (:head payload)))
116
- (:headTrackingEnabled config))
117
- :headFollowEyes true
118
- :eyeIntensity (:eyeIntensity config)
119
- :headIntensity (:headIntensity config)
120
- :headRoll 0
121
- :eyeDurationMs duration
122
- :headDurationMs duration
123
- :createdAt now-ms}))
124
-
125
- (defn normalize-cancel-request
126
- [command now-ms]
127
- (let [payload (data-map command)]
128
- {:type "eyeHeadTracking.requestCancel"
129
- :agency "eyeHeadTracking"
130
- :sourceAgency (request-source payload)
131
- :requestId (or (:requestId payload) (request-id "eyeHeadTracking:cancel" now-ms))
132
- :reason (or (:reason payload) "cancelled")
133
- :createdAt now-ms}))
@@ -1,106 +0,0 @@
1
- (ns polymer.eye-head.goap
2
- (:require [polymer.eye-head.domain :as domain]
3
- [polymer.eye-head.snippet :as snippet]))
4
-
5
- ;; Eye/Head planning accepts gaze requests from peer agencies and turns them
6
- ;; into local movement work. Animation requests are produced only after the
7
- ;; scheduler accepts the plan.
8
-
9
- (def supported-command-types
10
- #{"configure"
11
- "enable"
12
- "disable"
13
- "setTarget"
14
- "set-target"
15
- "requestGaze"
16
- "eyeHeadTracking.requestGaze"
17
- "reset"
18
- "eyeHeadTracking.requestReset"
19
- "cancel"
20
- "eyeHeadTracking.requestCancel"})
21
-
22
- (defn command-type
23
- [command]
24
- (:type command))
25
-
26
- (defn plan-gaze
27
- [command state now-ms]
28
- (if-not (domain/has-requested-target? command)
29
- [{:op "fail"
30
- :reason "missing-target"
31
- :commandType (command-type command)}]
32
- (let [request (domain/normalize-gaze-request command state now-ms)]
33
- (cond
34
- (not (get-in state [:config :enabled]))
35
- [{:op "ignore-request"
36
- :request request
37
- :reason "disabled"}]
38
-
39
- (not (domain/movement-enabled? request))
40
- [{:op "ignore-request"
41
- :request request
42
- :reason "movement-disabled"}]
43
-
44
- :else
45
- [{:op "queue-gaze"
46
- :request request
47
- :snippet (snippet/build-gaze-snippet request (:config state))}]))))
48
-
49
- (defn plan-reset
50
- [command state now-ms]
51
- (let [request (domain/normalize-reset-request command state now-ms)]
52
- (if (domain/movement-enabled? request)
53
- [{:op "queue-reset"
54
- :request request
55
- :snippet (snippet/build-gaze-snippet request (:config state))}]
56
- [{:op "ignore-request"
57
- :request request
58
- :reason "movement-disabled"}])))
59
-
60
- (defn plan-cancel
61
- [command now-ms]
62
- [{:op "cancel-active"
63
- :request (domain/normalize-cancel-request command now-ms)}])
64
-
65
- (defn command-steps
66
- [command state now-ms]
67
- (let [type (command-type command)]
68
- (cond
69
- (not (contains? supported-command-types type))
70
- [{:op "fail"
71
- :reason "unsupported-command"
72
- :commandType type}]
73
-
74
- (= "configure" type)
75
- [{:op "apply-config" :config (:config command)}
76
- {:op "publish-status" :reason "configured"}]
77
-
78
- (= "enable" type)
79
- [{:op "set-enabled" :enabled true}
80
- {:op "publish-status" :reason "enabled"}]
81
-
82
- (= "disable" type)
83
- [{:op "set-enabled" :enabled false}
84
- {:op "cancel-active"
85
- :request (domain/normalize-cancel-request
86
- (assoc command :reason "disabled")
87
- now-ms)}
88
- {:op "publish-status" :reason "disabled"}]
89
-
90
- (#{"reset" "eyeHeadTracking.requestReset"} type)
91
- (plan-reset command state now-ms)
92
-
93
- (#{"cancel" "eyeHeadTracking.requestCancel"} type)
94
- (plan-cancel command now-ms)
95
-
96
- :else
97
- (plan-gaze command state now-ms))))
98
-
99
- (defn plan-command
100
- [command state now-ms]
101
- (let [steps (command-steps command state now-ms)]
102
- {:agency "eyeHeadTracking"
103
- :commandType (command-type command)
104
- :createdAt now-ms
105
- :ok (not= "fail" (:op (first steps)))
106
- :steps steps}))
@@ -1,176 +0,0 @@
1
- (ns polymer.eye-head.scheduler
2
- (:require [polymer.eye-head.state :as state]))
3
-
4
- ;; The Eye/Head scheduler is the boundary that replaces or cancels movement
5
- ;; snippets. It publishes animation requests as data; the Animation agency owns
6
- ;; the runtime side effect of playing those snippets.
7
-
8
- (defn now-ms
9
- []
10
- (.now js/Date))
11
-
12
- (defn clear-timeout!
13
- [timeout-atom]
14
- (when-let [timeout @timeout-atom]
15
- (js/clearTimeout timeout)
16
- (reset! timeout-atom nil)))
17
-
18
- (defn queue-entry
19
- [step index]
20
- (assoc step
21
- :agency "eyeHeadTracking"
22
- :queueIndex index
23
- :queuedAt (now-ms)))
24
-
25
- (defn create-scheduler
26
- [{:keys [state-atom emit-event]}]
27
- (let [coalesce-timeout (atom nil)
28
- pending-work (atom nil)
29
- queue (atom [])
30
- disposed? (atom false)]
31
- (letfn [(enqueue! [step]
32
- (let [entry (queue-entry step (count @queue))]
33
- (swap! queue conj entry)
34
- entry))
35
-
36
- (emit-status! [reason]
37
- (emit-event {:type "eyeHeadTracking.status"
38
- :agency "eyeHeadTracking"
39
- :status (:status @state-atom)
40
- :enabled (get-in @state-atom [:config :enabled])
41
- :activeSnippetNames (:activeSnippetNames @state-atom)
42
- :reason reason
43
- :at (now-ms)}))
44
-
45
- (emit-remove-active! [reason]
46
- (doseq [name (:activeSnippetNames @state-atom)]
47
- (let [removed-at (now-ms)]
48
- (swap! state-atom state/record-removed name reason removed-at)
49
- (emit-event {:type "animation.requestRemoveSnippet"
50
- :agency "eyeHeadTracking"
51
- :requestId (str "eyeHeadTracking:remove:" removed-at)
52
- :name name
53
- :reason reason
54
- :queuedAt removed-at}))))
55
-
56
- (publish-work-now! []
57
- (when-not @disposed?
58
- (clear-timeout! coalesce-timeout)
59
- (when-let [{:keys [kind request snippet]} @pending-work]
60
- (reset! pending-work nil)
61
- (when (get-in @state-atom [:config :replaceExisting])
62
- (emit-remove-active! "replaced"))
63
- (let [published-at (now-ms)]
64
- (enqueue! {:op "publish-animation"
65
- :requestId (:requestId request)
66
- :name (:name snippet)})
67
- (if (= kind "reset")
68
- (swap! state-atom state/record-reset request snippet published-at)
69
- (swap! state-atom state/record-scheduled request snippet published-at))
70
- (emit-event {:type "animation.requestScheduleSnippet"
71
- :agency "eyeHeadTracking"
72
- :requestId (:requestId request)
73
- :snippet snippet
74
- :options {:autoPlay true
75
- :sourceAgency "eyeHeadTracking"}})))))
76
-
77
- (queue-work! [kind request snippet]
78
- (when-not @disposed?
79
- (let [queued-at (now-ms)
80
- work {:kind kind
81
- :request (assoc request :queuedAt queued-at)
82
- :snippet snippet}
83
- delay-ms (get-in @state-atom [:config :coalesceMs])]
84
- (reset! pending-work work)
85
- (swap! state-atom state/record-pending (:request work))
86
- (clear-timeout! coalesce-timeout)
87
- (enqueue! {:op "coalesce-work"
88
- :kind kind
89
- :requestId (:requestId request)
90
- :coalesceMs delay-ms})
91
- (if (pos? delay-ms)
92
- (reset! coalesce-timeout
93
- (js/setTimeout publish-work-now! delay-ms))
94
- (publish-work-now!)))))
95
-
96
- (cancel-pending! []
97
- (clear-timeout! coalesce-timeout)
98
- (reset! pending-work nil)
99
- (swap! state-atom assoc :pendingRequest nil))
100
-
101
- (ignore-request! [request reason]
102
- (let [ignored {:type "eyeHeadTracking.requestIgnored"
103
- :agency "eyeHeadTracking"
104
- :requestId (:requestId request)
105
- :reason reason
106
- :target (:target request)
107
- :ignoredAt (now-ms)}]
108
- (cancel-pending!)
109
- (swap! state-atom state/record-ignored ignored)
110
- (emit-event ignored)))
111
-
112
- (cancel-active! [request]
113
- (cancel-pending!)
114
- (emit-remove-active! (:reason request))
115
- (swap! state-atom state/record-cancel request)
116
- (emit-event {:type "eyeHeadTracking.cancelled"
117
- :agency "eyeHeadTracking"
118
- :requestId (:requestId request)
119
- :reason (:reason request)
120
- :at (now-ms)}))
121
-
122
- (execute-step! [step]
123
- (enqueue! step)
124
- (case (:op step)
125
- "apply-config"
126
- (do
127
- (swap! state-atom state/configure (:config step))
128
- (emit-status! (:reason step)))
129
-
130
- "set-enabled"
131
- (do
132
- (swap! state-atom state/set-enabled (:enabled step))
133
- (emit-status! (if (:enabled step) "enabled" "disabled")))
134
-
135
- "publish-status"
136
- (emit-status! (:reason step))
137
-
138
- "queue-gaze"
139
- (queue-work! "gaze" (:request step) (:snippet step))
140
-
141
- "queue-reset"
142
- (queue-work! "reset" (:request step) (:snippet step))
143
-
144
- "cancel-active"
145
- (cancel-active! (:request step))
146
-
147
- "ignore-request"
148
- (ignore-request! (:request step) (:reason step))
149
-
150
- "fail"
151
- (emit-event {:type "error"
152
- :agency "eyeHeadTracking"
153
- :message (:reason step)
154
- :commandType (:commandType step)})
155
-
156
- nil))]
157
- {:schedule
158
- (fn [plan]
159
- (when-not @disposed?
160
- (swap! state-atom state/record-plan plan)
161
- (doseq [step (:steps plan)]
162
- (execute-step! step))))
163
-
164
- :flush
165
- (fn []
166
- (publish-work-now!))
167
-
168
- :queue
169
- (fn []
170
- @queue)
171
-
172
- :dispose
173
- (fn []
174
- (reset! disposed? true)
175
- (cancel-pending!)
176
- (reset! queue []))})))