@quenty/valueobject 13.17.0 → 13.17.1-canary.545.2374fb2.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,6 +3,17 @@
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
+ ## [13.17.1-canary.545.2374fb2.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/valueobject@13.17.0...@quenty/valueobject@13.17.1-canary.545.2374fb2.0) (2025-04-05)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
12
+
13
+
14
+
15
+
16
+
6
17
  # [13.17.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/valueobject@13.16.2...@quenty/valueobject@13.17.0) (2025-04-02)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/valueobject
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/valueobject",
3
- "version": "13.17.0",
3
+ "version": "13.17.1-canary.545.2374fb2.0",
4
4
  "description": "To work like value objects in Roblox and track a single item with .Changed events",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -26,16 +26,16 @@
26
26
  "Quenty"
27
27
  ],
28
28
  "dependencies": {
29
- "@quenty/brio": "^14.17.0",
30
- "@quenty/ducktype": "^5.8.1",
31
- "@quenty/loader": "^10.8.0",
32
- "@quenty/maid": "^3.4.0",
33
- "@quenty/rx": "^13.17.0",
34
- "@quenty/signal": "^7.10.0",
35
- "@quenty/valuebaseutils": "^13.17.0"
29
+ "@quenty/brio": "14.17.1-canary.545.2374fb2.0",
30
+ "@quenty/ducktype": "5.8.2-canary.545.2374fb2.0",
31
+ "@quenty/loader": "10.8.1-canary.545.2374fb2.0",
32
+ "@quenty/maid": "3.4.1-canary.545.2374fb2.0",
33
+ "@quenty/rx": "13.17.1-canary.545.2374fb2.0",
34
+ "@quenty/signal": "7.10.1-canary.545.2374fb2.0",
35
+ "@quenty/valuebaseutils": "13.17.1-canary.545.2374fb2.0"
36
36
  },
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "e8ea56930e65322fcffc05a1556d5df988068f0b"
40
+ "gitHead": "2374fb2b043cfbe0e9b507b3316eec46a4e353a0"
41
41
  }
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[=[
2
3
  To work like value objects in Roblox and track a single item,
3
4
  with `.Changed` events
@@ -14,23 +15,55 @@ local Observable = require("Observable")
14
15
  local RxValueBaseUtils = require("RxValueBaseUtils")
15
16
  local Signal = require("Signal")
16
17
  local ValueBaseUtils = require("ValueBaseUtils")
18
+ local _Subscription = require("Subscription")
19
+ local _Rx = require("Rx")
17
20
 
18
21
  local EMPTY_FUNCTION = function() end
19
22
 
20
23
  local ValueObject = {}
21
24
  ValueObject.ClassName = "ValueObject"
22
25
 
26
+ export type TypeChecker = (value: any) -> (boolean, string?)
27
+
28
+ export type ValueObjectTypeArg = string | TypeChecker
29
+
30
+ export type ValueObject<T> = typeof(setmetatable(
31
+ {} :: {
32
+ --[=[
33
+ The value of the ValueObject
34
+ @prop Value T
35
+ @within ValueObject
36
+ ]=]
37
+ Value: T,
38
+
39
+ --[=[
40
+ Event fires when the value's object value change
41
+ @prop Changed Signal<T> -- fires with oldValue, newValue, ...
42
+ @within ValueObject
43
+ ]=]
44
+ Changed: Signal.Signal<(T, T, ...any)>,
45
+ LastEventContext: { any },
46
+
47
+ _checkType: ValueObjectTypeArg?,
48
+ _value: T,
49
+ _default: T?,
50
+ _lastEventContext: { any }?,
51
+ _lastMountedSub: _Subscription.Subscription<(T, ...any)>?,
52
+ },
53
+ ValueObject
54
+ ))
55
+
23
56
  --[=[
24
57
  Constructs a new value object
25
58
  @param baseValue T
26
- @param checkType string | nil | (value: T) -> (boolean, string)
59
+ @param checkType string? | (value: T) -> (boolean, string?)
27
60
  @return ValueObject
28
61
  ]=]
29
- function ValueObject.new(baseValue, checkType)
62
+ function ValueObject.new<T>(baseValue: T?, checkType: ValueObjectTypeArg?): ValueObject<T>
30
63
  local self = setmetatable({
31
- _value = baseValue;
32
- _default = baseValue;
33
- _checkType = checkType;
64
+ _value = baseValue,
65
+ _default = baseValue,
66
+ _checkType = checkType,
34
67
  }, ValueObject)
35
68
 
36
69
  if type(checkType) == "string" then
@@ -41,22 +74,16 @@ function ValueObject.new(baseValue, checkType)
41
74
  assert(checkType(baseValue))
42
75
  end
43
76
 
44
- return self
77
+ return self :: any
45
78
  end
46
79
 
47
- --[=[
48
- Event fires when the value's object value change
49
- @prop Changed Signal<T> -- fires with oldValue, newValue, ...
50
- @within ValueObject
51
- ]=]
52
-
53
80
  --[=[
54
81
  Returns the current check type, if any
55
82
 
56
- @return string | nil | (value: T) -> (boolean, string)
83
+ @return string? | (value: T) -> (boolean, string)
57
84
  ]=]
58
- function ValueObject:GetCheckType()
59
- return rawget(self, "_checkType")
85
+ function ValueObject.GetCheckType<T>(self: ValueObject<T>): ValueObjectTypeArg?
86
+ return rawget(self :: any, "_checkType")
60
87
  end
61
88
 
62
89
  --[=[
@@ -64,7 +91,7 @@ end
64
91
  @param observable Observable<T>
65
92
  @return ValueObject<T>
66
93
  ]=]
67
- function ValueObject.fromObservable(observable)
94
+ function ValueObject.fromObservable<T>(observable: Observable.Observable<T>): ValueObject<T>
68
95
  local result = ValueObject.new()
69
96
 
70
97
  result:Mount(observable)
@@ -77,11 +104,11 @@ end
77
104
  @param value any
78
105
  @return boolean
79
106
  ]=]
80
- function ValueObject.isValueObject(value)
107
+ function ValueObject.isValueObject(value: any): boolean
81
108
  return DuckTypeUtils.isImplementation(ValueObject, value)
82
109
  end
83
110
 
84
- function ValueObject:_toMountableObservable(value)
111
+ function ValueObject._toMountableObservable<T>(_self: ValueObject<T>, value: T | Observable.Observable<T> | ValueBase)
85
112
  if Observable.isObservable(value) then
86
113
  return value
87
114
  elseif typeof(value) == "Instance" then
@@ -91,9 +118,9 @@ function ValueObject:_toMountableObservable(value)
91
118
  end
92
119
  elseif type(value) == "table" then
93
120
  if ValueObject.isValueObject(value) then
94
- return value:Observe()
95
- -- elseif Promise.isPromise(value) then
96
- -- return Rx.fromPromise(value)
121
+ return (value :: any):Observe()
122
+ -- elseif Promise.isPromise(value) then
123
+ -- return Rx.fromPromise(value)
97
124
  end
98
125
  end
99
126
 
@@ -106,7 +133,7 @@ end
106
133
  @param value Observable | T
107
134
  @return MaidTask
108
135
  ]=]
109
- function ValueObject:Mount(value)
136
+ function ValueObject.Mount<T>(self: ValueObject<T>, value: Observable.Observable<T> | T | ValueBase): () -> ()
110
137
  local observable = self:_toMountableObservable(value)
111
138
  if observable then
112
139
  self:_cleanupLastMountedSub()
@@ -115,36 +142,36 @@ function ValueObject:Mount(value)
115
142
  ValueObject._applyValue(self, ...)
116
143
  end)
117
144
 
118
- rawset(self, "_lastMountedSub", sub)
145
+ rawset(self :: any, "_lastMountedSub", sub)
119
146
 
120
147
  return function()
121
- if rawget(self, "_lastMountedSub") == sub then
148
+ if rawget(self :: any, "_lastMountedSub") == sub then
122
149
  self:_cleanupLastMountedSub()
123
150
  end
124
151
  end
125
152
  else
126
153
  self:_cleanupLastMountedSub()
127
154
 
128
- ValueObject._applyValue(self, value)
155
+ ValueObject._applyValue(self, value :: T)
129
156
 
130
157
  return EMPTY_FUNCTION
131
158
  end
132
159
  end
133
160
 
134
- function ValueObject:_cleanupLastMountedSub()
135
- local lastSub = rawget(self, "_lastMountedSub")
161
+ function ValueObject._cleanupLastMountedSub<T>(self: ValueObject<T>)
162
+ local lastSub = rawget(self :: any, "_lastMountedSub")
136
163
  if lastSub then
137
- rawset(self, "_lastMountedSub", nil)
164
+ rawset(self :: any, "_lastMountedSub", nil)
138
165
  MaidTaskUtils.doTask(lastSub)
139
166
  end
140
167
  end
141
168
 
142
169
  --[=[
143
170
  Observes the current value of the ValueObject
144
- @return Observable<T>
171
+ @return Observable<T?>
145
172
  ]=]
146
- function ValueObject:Observe()
147
- local found = rawget(self, "_observable")
173
+ function ValueObject.Observe<T>(self: ValueObject<T>): Observable.Observable<T?>
174
+ local found = rawget(self :: any, "_observable")
148
175
  if found then
149
176
  return found
150
177
  end
@@ -161,8 +188,8 @@ function ValueObject:Observe()
161
188
  sub:Fire(newValue, ...)
162
189
  end)
163
190
 
164
- local args = rawget(self, "_lastEventContext")
165
- local value = rawget(self, "_value")
191
+ local args = rawget(self :: any, "_lastEventContext")
192
+ local value = rawget(self :: any, "_value")
166
193
  if args then
167
194
  sub:Fire(value, table.unpack(args, 1, args.n))
168
195
  else
@@ -173,7 +200,7 @@ function ValueObject:Observe()
173
200
  end)
174
201
 
175
202
  -- We use a lot of these so let's cache the result which reduces the number of tables we have here
176
- rawset(self, "_observable", created)
203
+ rawset(self :: any, "_observable", created)
177
204
  return created
178
205
  end
179
206
 
@@ -183,7 +210,10 @@ end
183
210
  @param condition function | nil -- optional
184
211
  @return Observable<Brio<T>>
185
212
  ]=]
186
- function ValueObject:ObserveBrio(condition)
213
+ function ValueObject.ObserveBrio<T>(
214
+ self: ValueObject<T>,
215
+ condition: _Rx.Predicate<T>?
216
+ ): Observable.Observable<Brio.Brio<T>>
187
217
  assert(type(condition) == "function" or condition == nil, "Bad condition")
188
218
 
189
219
  return Observable.new(function(sub)
@@ -196,7 +226,7 @@ function ValueObject:ObserveBrio(condition)
196
226
 
197
227
  local maid = Maid.new()
198
228
 
199
- local function handleNewValue(newValue, ...)
229
+ local function handleNewValue(newValue: T, ...)
200
230
  if not condition or condition(newValue) then
201
231
  local brio = Brio.new(newValue, ...)
202
232
  maid._current = brio
@@ -206,11 +236,11 @@ function ValueObject:ObserveBrio(condition)
206
236
  end
207
237
  end
208
238
 
209
- maid:GiveTask(self.Changed:Connect(function(newValue, _, ...)
239
+ maid:GiveTask(self.Changed:Connect(function(newValue, _previous, ...)
210
240
  handleNewValue(newValue, ...)
211
241
  end))
212
242
 
213
- local args = rawget(self, "_lastEventContext")
243
+ local args = rawget(self :: any, "_lastEventContext")
214
244
  if args then
215
245
  handleNewValue(self.Value, table.unpack(args, 1, args.n))
216
246
  else
@@ -218,7 +248,7 @@ function ValueObject:ObserveBrio(condition)
218
248
  end
219
249
 
220
250
  return maid
221
- end)
251
+ end) :: any
222
252
  end
223
253
 
224
254
  --[=[
@@ -237,21 +267,21 @@ end
237
267
  @param ... any -- Additional args. Can be used to pass event changing state args with value
238
268
  @return () -> () -- Cleanup
239
269
  ]=]
240
- function ValueObject:SetValue(value, ...)
270
+ function ValueObject.SetValue<T>(self: ValueObject<T>, value: T, ...)
241
271
  self:_cleanupLastMountedSub()
242
272
 
243
273
  ValueObject._applyValue(self, value, ...)
244
274
 
245
275
  return function()
246
- if rawget(self, "_value") == value then
247
- ValueObject._applyValue(self, rawget(self, "_default"))
276
+ if rawget(self :: any, "_value") == value then
277
+ ValueObject._applyValue(self, rawget(self :: any, "_default"))
248
278
  end
249
279
  end
250
280
  end
251
281
 
252
- function ValueObject:_applyValue(value, ...)
253
- local previous = rawget(self, "_value")
254
- local checkType = rawget(self, "_checkType")
282
+ function ValueObject._applyValue<T>(self: ValueObject<T>, value: T, ...)
283
+ local previous = rawget(self :: any, "_value")
284
+ local checkType = rawget(self :: any, "_checkType")
255
285
 
256
286
  if type(checkType) == "string" then
257
287
  if typeof(value) ~= checkType then
@@ -263,40 +293,35 @@ function ValueObject:_applyValue(value, ...)
263
293
 
264
294
  if previous ~= value then
265
295
  if select("#", ...) > 0 then
266
- rawset(self, "_lastEventContext", table.pack(...))
296
+ rawset(self :: any, "_lastEventContext", table.pack(...))
267
297
  else
268
- rawset(self, "_lastEventContext", nil)
298
+ rawset(self :: any, "_lastEventContext", nil)
269
299
  end
270
300
 
271
- rawset(self, "_value", value)
272
- local changed = rawget(self, "Changed")
301
+ rawset(self :: any, "_value", value)
302
+ local changed = rawget(self :: any, "Changed")
273
303
  if changed then
274
304
  changed:Fire(value, previous, ...)
275
305
  end
276
306
  end
277
307
  end
278
308
 
279
- --[=[
280
- The value of the ValueObject
281
- @prop Value T
282
- @within ValueObject
283
- ]=]
284
309
  function ValueObject:__index(index)
285
310
  if ValueObject[index] then
286
311
  return ValueObject[index]
287
312
  elseif index == "Value" then
288
- return self._value
313
+ return rawget(self :: any, "_value")
289
314
  elseif index == "Changed" then
290
315
  -- Defer construction of Changed event until something needs it, since a lot
291
316
  -- of times we don't need it
292
317
 
293
318
  local signal = Signal.new() -- :Fire(newValue, oldValue, ...)
294
319
 
295
- rawset(self, "Changed", signal)
320
+ rawset(self :: any, "Changed", signal)
296
321
 
297
322
  return signal
298
323
  elseif index == "LastEventContext" then
299
- local args = rawget(self, "_lastEventContext")
324
+ local args = rawget(self :: any, "_lastEventContext")
300
325
  if args then
301
326
  return table.unpack(args, 1, args.n)
302
327
  else
@@ -325,18 +350,18 @@ end
325
350
 
326
351
  Does not fire the event since 3.5.0
327
352
  ]=]
328
- function ValueObject:Destroy()
329
- rawset(self, "_value", nil)
353
+ function ValueObject.Destroy<T>(self: ValueObject<T>)
354
+ rawset(self :: any, "_value", nil)
330
355
 
331
356
  self:_cleanupLastMountedSub()
332
357
 
333
358
  -- Avoid using a maid here because we make a LOT of ValueObjects
334
- local changed = rawget(self, "Changed")
359
+ local changed = rawget(self :: any, "Changed")
335
360
  if changed then
336
361
  changed:Destroy()
337
362
  end
338
363
 
339
- setmetatable(self, nil)
364
+ setmetatable(self :: any, nil)
340
365
  end
341
366
 
342
367
  return ValueObject
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[=[
2
3
  Utils that work with Roblox Value objects (and also ValueObject)
3
4
  @class ValueObjectUtils
@@ -18,7 +19,7 @@ local ValueObjectUtils = {}
18
19
  @param to ValueObject<T>
19
20
  @return MaidTask
20
21
  ]=]
21
- function ValueObjectUtils.syncValue(from, to)
22
+ function ValueObjectUtils.syncValue<T>(from: ValueObject.ValueObject<T>, to: ValueObject.ValueObject<T>): Maid.Maid
22
23
  local maid = Maid.new()
23
24
  to.Value = from.Value
24
25
 
@@ -31,10 +32,12 @@ end
31
32
 
32
33
  --[=[
33
34
  Observes the current value of the ValueObject
35
+
36
+ @deprecated 13.18.0
34
37
  @param valueObject ValueObject<T>
35
38
  @return Observable<T>
36
39
  ]=]
37
- function ValueObjectUtils.observeValue(valueObject)
40
+ function ValueObjectUtils.observeValue<T>(valueObject: ValueObject.ValueObject<T>): Observable.Observable<T>
38
41
  assert(ValueObject.isValueObject(valueObject), "Bad valueObject")
39
42
 
40
43
  return valueObject:Observe()
@@ -45,7 +48,7 @@ end
45
48
  @param valueObject ValueObject<T>
46
49
  @return Observable<Brio<T>>
47
50
  ]=]
48
- function ValueObjectUtils.observeValueBrio(valueObject)
51
+ function ValueObjectUtils.observeValueBrio<T>(valueObject: ValueObject.ValueObject<T>): Observable.Observable<Brio.Brio<T>>
49
52
  assert(valueObject, "Bad valueObject")
50
53
 
51
54
  return Observable.new(function(sub)
@@ -62,8 +65,7 @@ function ValueObjectUtils.observeValueBrio(valueObject)
62
65
  refire()
63
66
 
64
67
  return maid
65
- end)
68
+ end) :: any
66
69
  end
67
70
 
68
-
69
71
  return ValueObjectUtils