@quenty/binder 9.0.0-canary.ff9fb44.0 → 9.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.
- package/CHANGELOG.md +120 -1
- package/package.json +12 -11
- package/src/Shared/Binder.lua +176 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,126 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
# [9.0.0
|
|
6
|
+
# [9.0.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.27.0...@quenty/binder@9.0.0) (2023-10-11)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Binder has warning about constructing other binders ([3729779](https://github.com/Quenty/NevermoreEngine/commit/37297794d59310a53a3659a406f1e6e266460283))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [8.27.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.26.0...@quenty/binder@8.27.0) (2023-09-21)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @quenty/binder
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# [8.26.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.25.0...@quenty/binder@8.26.0) (2023-09-04)
|
|
26
|
+
|
|
27
|
+
**Note:** Version bump only for package @quenty/binder
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# [8.25.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.24.0...@quenty/binder@8.25.0) (2023-08-23)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
* Add Binder:ObserveAllBrio() ([f68cccc](https://github.com/Quenty/NevermoreEngine/commit/f68cccc8b74acf770ca16888d31c0bb82436d3b0))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# [8.24.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.23.0...@quenty/binder@8.24.0) (2023-08-01)
|
|
45
|
+
|
|
46
|
+
**Note:** Version bump only for package @quenty/binder
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# [8.23.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.22.0...@quenty/binder@8.23.0) (2023-07-28)
|
|
53
|
+
|
|
54
|
+
**Note:** Version bump only for package @quenty/binder
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# [8.22.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.21.0...@quenty/binder@8.22.0) (2023-07-23)
|
|
61
|
+
|
|
62
|
+
**Note:** Version bump only for package @quenty/binder
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# [8.21.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.20.0...@quenty/binder@8.21.0) (2023-07-15)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Features
|
|
72
|
+
|
|
73
|
+
* Add Binder:Create() API surface ([0e78a1c](https://github.com/Quenty/NevermoreEngine/commit/0e78a1ce69e2469f61059b641b2000ddd0c7d758))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# [8.20.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.19.1...@quenty/binder@8.20.0) (2023-07-10)
|
|
80
|
+
|
|
81
|
+
**Note:** Version bump only for package @quenty/binder
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## [8.19.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.19.0...@quenty/binder@8.19.1) (2023-06-24)
|
|
88
|
+
|
|
89
|
+
**Note:** Version bump only for package @quenty/binder
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# [8.19.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.18.1...@quenty/binder@8.19.0) (2023-06-24)
|
|
96
|
+
|
|
97
|
+
**Note:** Version bump only for package @quenty/binder
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## [8.18.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.18.0...@quenty/binder@8.18.1) (2023-06-23)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
### Bug Fixes
|
|
107
|
+
|
|
108
|
+
* Fix binder args failing in no-arg non-service-provided interface ([36f3417](https://github.com/Quenty/NevermoreEngine/commit/36f3417debd56f478fea591133f78d2a0c521dab))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# [8.18.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.17.0...@quenty/binder@8.18.0) (2023-06-17)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
### Features
|
|
118
|
+
|
|
119
|
+
* Binders can be initialized by the ServiceBag directly instead of requireing a BinderProvider ([28ce17f](https://github.com/Quenty/NevermoreEngine/commit/28ce17fe254b7fdce115132244ca1a6e8693d24b))
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# [8.17.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.16.0...@quenty/binder@8.17.0) (2023-06-05)
|
|
7
126
|
|
|
8
127
|
**Note:** Version bump only for package @quenty/binder
|
|
9
128
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/binder",
|
|
3
|
-
"version": "9.0.0
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "Utility object to Bind a class to Roblox object, and associated helper methods",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,18 +25,19 @@
|
|
|
25
25
|
"Quenty"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@quenty/baseobject": "
|
|
29
|
-
"@quenty/brio": "
|
|
30
|
-
"@quenty/instanceutils": "
|
|
31
|
-
"@quenty/linkutils": "
|
|
32
|
-
"@quenty/loader": "
|
|
33
|
-
"@quenty/maid": "2.
|
|
34
|
-
"@quenty/promise": "
|
|
35
|
-
"@quenty/
|
|
36
|
-
"@quenty/
|
|
28
|
+
"@quenty/baseobject": "^7.0.0",
|
|
29
|
+
"@quenty/brio": "^9.0.0",
|
|
30
|
+
"@quenty/instanceutils": "^8.0.0",
|
|
31
|
+
"@quenty/linkutils": "^8.0.0",
|
|
32
|
+
"@quenty/loader": "^7.0.0",
|
|
33
|
+
"@quenty/maid": "^2.6.0",
|
|
34
|
+
"@quenty/promise": "^7.0.0",
|
|
35
|
+
"@quenty/rx": "^8.0.0",
|
|
36
|
+
"@quenty/signal": "^3.0.0",
|
|
37
|
+
"@quenty/valueobject": "^8.0.0"
|
|
37
38
|
},
|
|
38
39
|
"publishConfig": {
|
|
39
40
|
"access": "public"
|
|
40
41
|
},
|
|
41
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "fdeae46099587019ec5fc15317dc673aed379400"
|
|
42
43
|
}
|
package/src/Shared/Binder.lua
CHANGED
|
@@ -31,8 +31,10 @@ local CollectionService = game:GetService("CollectionService")
|
|
|
31
31
|
|
|
32
32
|
local Maid = require("Maid")
|
|
33
33
|
local MaidTaskUtils = require("MaidTaskUtils")
|
|
34
|
-
local
|
|
34
|
+
local Observable = require("Observable")
|
|
35
35
|
local promiseBoundClass = require("promiseBoundClass")
|
|
36
|
+
local Signal = require("Signal")
|
|
37
|
+
local Brio = require("Brio")
|
|
36
38
|
|
|
37
39
|
local Binder = {}
|
|
38
40
|
Binder.__index = Binder
|
|
@@ -65,12 +67,22 @@ Binder.ClassName = "Binder"
|
|
|
65
67
|
@return Binder<T>
|
|
66
68
|
]=]
|
|
67
69
|
function Binder.new(tagName, constructor, ...)
|
|
70
|
+
assert(type(tagName) == "string", "Bad tagName")
|
|
71
|
+
|
|
68
72
|
local self = setmetatable({}, Binder)
|
|
69
73
|
|
|
70
74
|
self._tagName = assert(tagName, "Bad argument 'tagName', expected string")
|
|
71
75
|
self._constructor = assert(constructor, "Bad argument 'constructor', expected table or function")
|
|
76
|
+
self._defaultClassType = "Folder"
|
|
77
|
+
self.ServiceName = self._tagName .. "Binder"
|
|
72
78
|
|
|
73
|
-
self
|
|
79
|
+
if Binder.isBinder(self._constructor) then
|
|
80
|
+
error("Cannot make a binder that constructs another binder")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if select("#", ...) > 0 then
|
|
84
|
+
self._args = { ... }
|
|
85
|
+
end
|
|
74
86
|
|
|
75
87
|
return self
|
|
76
88
|
end
|
|
@@ -107,6 +119,11 @@ end
|
|
|
107
119
|
@param ... any
|
|
108
120
|
]=]
|
|
109
121
|
function Binder:Init(...)
|
|
122
|
+
if self._initialized then
|
|
123
|
+
return
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
self._initialized = true
|
|
110
127
|
self._maid = Maid.new()
|
|
111
128
|
|
|
112
129
|
self._instToClass = {} -- [inst] = class
|
|
@@ -114,22 +131,50 @@ function Binder:Init(...)
|
|
|
114
131
|
self._pendingInstSet = {} -- [inst] = true
|
|
115
132
|
|
|
116
133
|
self._listeners = {} -- [inst] = callback
|
|
117
|
-
|
|
134
|
+
|
|
135
|
+
if select("#", ...) > 0 then
|
|
136
|
+
if not self._args then
|
|
137
|
+
self._args = {...}
|
|
138
|
+
elseif not self:_argsMatch(...) then
|
|
139
|
+
warn("[Binder.Init] - Non-matching args from :Init() and .new()")
|
|
140
|
+
end
|
|
141
|
+
elseif not self._args then
|
|
142
|
+
-- Binder.new() would have captured args if we had them
|
|
143
|
+
self._args = {}
|
|
144
|
+
end
|
|
118
145
|
|
|
119
146
|
self._maid._warning = task.delay(5, function()
|
|
120
147
|
warn(("Binder %q is not loaded. Call :Start() on it!"):format(self._tagName))
|
|
121
148
|
end)
|
|
122
149
|
end
|
|
123
150
|
|
|
151
|
+
function Binder:_argsMatch(...)
|
|
152
|
+
if #self._args ~= select("#", ...) then
|
|
153
|
+
return false
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
for index, value in pairs({...}) do
|
|
157
|
+
if self._args[index] ~= value then
|
|
158
|
+
return false
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
return true
|
|
163
|
+
end
|
|
164
|
+
|
|
124
165
|
--[=[
|
|
125
166
|
Listens for new instances and connects to the GetInstanceAddedSignal() and removed signal!
|
|
126
167
|
]=]
|
|
127
168
|
function Binder:Start()
|
|
128
|
-
if self.
|
|
169
|
+
if not self._initialized then
|
|
170
|
+
self:Init()
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if self._started then
|
|
129
174
|
return
|
|
130
175
|
end
|
|
131
176
|
self._maid._warning = nil
|
|
132
|
-
self.
|
|
177
|
+
self._started = true
|
|
133
178
|
|
|
134
179
|
for _, inst in pairs(CollectionService:GetTagged(self._tagName)) do
|
|
135
180
|
task.spawn(self._add, self, inst)
|
|
@@ -161,9 +206,95 @@ function Binder:GetConstructor()
|
|
|
161
206
|
return self._constructor
|
|
162
207
|
end
|
|
163
208
|
|
|
209
|
+
--[=[
|
|
210
|
+
Observes the current value of the instance
|
|
211
|
+
|
|
212
|
+
@param instance Instance
|
|
213
|
+
@return Observable<T | nil>
|
|
214
|
+
]=]
|
|
215
|
+
function Binder:Observe(instance)
|
|
216
|
+
assert(typeof(instance) == "Instance", "Bad instance")
|
|
217
|
+
|
|
218
|
+
return Observable.new(function(sub)
|
|
219
|
+
local maid = Maid.new()
|
|
220
|
+
|
|
221
|
+
maid:GiveTask(self:ObserveInstance(instance, function(...)
|
|
222
|
+
sub:Fire(...)
|
|
223
|
+
end))
|
|
224
|
+
sub:Fire(self:Get(instance))
|
|
225
|
+
|
|
226
|
+
return maid
|
|
227
|
+
end)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
--[=[
|
|
231
|
+
Observes all entries in the binder
|
|
232
|
+
|
|
233
|
+
@return Observable<Brio<T>>
|
|
234
|
+
]=]
|
|
235
|
+
function Binder:ObserveAllBrio()
|
|
236
|
+
return Observable.new(function(sub)
|
|
237
|
+
local maid = Maid.new()
|
|
238
|
+
|
|
239
|
+
local function handleNewClass(class)
|
|
240
|
+
local brio = Brio.new(class)
|
|
241
|
+
maid[class] = brio
|
|
242
|
+
|
|
243
|
+
sub:Fire(brio)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
maid:GiveTask(self:GetClassAddedSignal():Connect(handleNewClass))
|
|
247
|
+
|
|
248
|
+
for _, item in pairs(self:GetAll()) do
|
|
249
|
+
handleNewClass(item)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
maid:GiveTask(self:GetClassRemovingSignal():Connect(function(class)
|
|
253
|
+
maid[class] = nil
|
|
254
|
+
end))
|
|
255
|
+
|
|
256
|
+
return maid
|
|
257
|
+
end)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
--[=[
|
|
261
|
+
Observes a bound class on a given instance.
|
|
262
|
+
|
|
263
|
+
@param instance Instance
|
|
264
|
+
@return Observable<Brio<T>>
|
|
265
|
+
]=]
|
|
266
|
+
function Binder:ObserveBrio(instance)
|
|
267
|
+
assert(typeof(instance) == "Instance", "Bad instance")
|
|
268
|
+
|
|
269
|
+
return Observable.new(function(sub)
|
|
270
|
+
local maid = Maid.new()
|
|
271
|
+
|
|
272
|
+
local function handleClassChanged(class)
|
|
273
|
+
if class then
|
|
274
|
+
local brio = Brio.new(class)
|
|
275
|
+
maid._lastBrio = brio
|
|
276
|
+
|
|
277
|
+
sub:Fire(brio)
|
|
278
|
+
else
|
|
279
|
+
maid._lastBrio = nil
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
maid:GiveTask(self:ObserveInstance(instance, handleClassChanged))
|
|
284
|
+
handleClassChanged(self:Get(instance))
|
|
285
|
+
|
|
286
|
+
return maid
|
|
287
|
+
end)
|
|
288
|
+
end
|
|
289
|
+
|
|
164
290
|
--[=[
|
|
165
291
|
Fired when added, and then after removal, but before destroy!
|
|
166
292
|
|
|
293
|
+
:::info
|
|
294
|
+
This is before [Rx] so it doesn't follow the same Rx pattern. See [Binder.Observe] for
|
|
295
|
+
an [Rx] compatible interface.
|
|
296
|
+
:::
|
|
297
|
+
|
|
167
298
|
@param inst Instance
|
|
168
299
|
@param callback function
|
|
169
300
|
@return function -- Cleanup function
|
|
@@ -318,6 +449,28 @@ function Binder:Bind(inst)
|
|
|
318
449
|
return self:Get(inst)
|
|
319
450
|
end
|
|
320
451
|
|
|
452
|
+
--[=[
|
|
453
|
+
Tags the instance with the tag for the binder
|
|
454
|
+
|
|
455
|
+
@param inst Instance
|
|
456
|
+
]=]
|
|
457
|
+
function Binder:Tag(inst)
|
|
458
|
+
assert(typeof(inst) == "Instance", "Bad inst")
|
|
459
|
+
|
|
460
|
+
CollectionService:AddTag(inst, self._tagName)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
--[=[
|
|
464
|
+
Untags the instance with the tag for the binder
|
|
465
|
+
|
|
466
|
+
@param inst Instance
|
|
467
|
+
]=]
|
|
468
|
+
function Binder:Untag(inst)
|
|
469
|
+
assert(typeof(inst) == "Instance", "Bad inst")
|
|
470
|
+
|
|
471
|
+
CollectionService:RemoveTag(inst, self._tagName)
|
|
472
|
+
end
|
|
473
|
+
|
|
321
474
|
--[=[
|
|
322
475
|
Unbinds the instance by removing the tag.
|
|
323
476
|
|
|
@@ -389,6 +542,24 @@ function Binder:Promise(inst, cancelToken)
|
|
|
389
542
|
return promiseBoundClass(self, inst, cancelToken)
|
|
390
543
|
end
|
|
391
544
|
|
|
545
|
+
--[=[
|
|
546
|
+
Creates a new class tagged with this binder's instance
|
|
547
|
+
|
|
548
|
+
@param className string | nil
|
|
549
|
+
@return Instance
|
|
550
|
+
]=]
|
|
551
|
+
function Binder:Create(className)
|
|
552
|
+
assert(type(className) == "string" or className == nil, "Bad className")
|
|
553
|
+
|
|
554
|
+
local instance = Instance.new(className or self._defaultClassType)
|
|
555
|
+
instance.Name = self._tagName
|
|
556
|
+
instance.Archivable = false
|
|
557
|
+
|
|
558
|
+
self:Tag(instance)
|
|
559
|
+
|
|
560
|
+
return instance
|
|
561
|
+
end
|
|
562
|
+
|
|
392
563
|
function Binder:_add(inst)
|
|
393
564
|
assert(typeof(inst) == "Instance", "Argument 'inst' is not an Instance")
|
|
394
565
|
|