@quenty/binder 9.0.0-canary.367.e9fdcbc.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 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-canary.367.e9fdcbc.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/binder@8.16.0...@quenty/binder@9.0.0-canary.367.e9fdcbc.0) (2023-06-05)
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-canary.367.e9fdcbc.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": "6.2.1",
29
- "@quenty/brio": "8.13.0",
30
- "@quenty/instanceutils": "7.14.0",
31
- "@quenty/linkutils": "7.14.0",
32
- "@quenty/loader": "6.2.1",
33
- "@quenty/maid": "2.5.0",
34
- "@quenty/promise": "6.5.0",
35
- "@quenty/signal": "2.4.0",
36
- "@quenty/valueobject": "8.0.0-canary.367.e9fdcbc.0"
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": "e9fdcbc6ea1d46e068bf42a08b833099e9005259"
42
+ "gitHead": "fdeae46099587019ec5fc15317dc673aed379400"
42
43
  }
@@ -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 Signal = require("Signal")
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:Init(...)
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
@@ -119,22 +131,50 @@ function Binder:Init(...)
119
131
  self._pendingInstSet = {} -- [inst] = true
120
132
 
121
133
  self._listeners = {} -- [inst] = callback
122
- self._args = {...}
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
123
145
 
124
146
  self._maid._warning = task.delay(5, function()
125
147
  warn(("Binder %q is not loaded. Call :Start() on it!"):format(self._tagName))
126
148
  end)
127
149
  end
128
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
+
129
165
  --[=[
130
166
  Listens for new instances and connects to the GetInstanceAddedSignal() and removed signal!
131
167
  ]=]
132
168
  function Binder:Start()
133
- if self._loaded then
169
+ if not self._initialized then
170
+ self:Init()
171
+ end
172
+
173
+ if self._started then
134
174
  return
135
175
  end
136
176
  self._maid._warning = nil
137
- self._loaded = true
177
+ self._started = true
138
178
 
139
179
  for _, inst in pairs(CollectionService:GetTagged(self._tagName)) do
140
180
  task.spawn(self._add, self, inst)
@@ -166,9 +206,95 @@ function Binder:GetConstructor()
166
206
  return self._constructor
167
207
  end
168
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
+
169
290
  --[=[
170
291
  Fired when added, and then after removal, but before destroy!
171
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
+
172
298
  @param inst Instance
173
299
  @param callback function
174
300
  @return function -- Cleanup function
@@ -323,6 +449,28 @@ function Binder:Bind(inst)
323
449
  return self:Get(inst)
324
450
  end
325
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
+
326
474
  --[=[
327
475
  Unbinds the instance by removing the tag.
328
476
 
@@ -394,6 +542,24 @@ function Binder:Promise(inst, cancelToken)
394
542
  return promiseBoundClass(self, inst, cancelToken)
395
543
  end
396
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
+
397
563
  function Binder:_add(inst)
398
564
  assert(typeof(inst) == "Instance", "Argument 'inst' is not an Instance")
399
565