@rbxts/replion 1.0.9 → 1.0.11

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/README.md CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  ## Install
4
4
  Install with [wally](https://wally.run/):\
5
- `Replion = "shouxtech/replion@1.0.9"`
5
+ `Replion = "shouxtech/replion@1.0.11"`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/replion",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "",
5
5
  "main": "src/init.lua",
6
6
  "scripts": {},
package/src/Client.lua CHANGED
@@ -58,7 +58,7 @@ function Client.new(channel: string, data: Shared.GenericDataTable)
58
58
  return self;
59
59
  end;
60
60
 
61
- function Client:get(key: (string | {string})?)
61
+ function Client:get(key: (string | { string })?)
62
62
  if not key then return self.data; end;
63
63
  if typeof(key) == 'table' then
64
64
  return Shared.getNestedValue(self.data, key);
@@ -67,51 +67,73 @@ function Client:get(key: (string | {string})?)
67
67
  return self.data[key];
68
68
  end;
69
69
 
70
- function Client:observe(key: string?, callback: Observer)
71
- if not key then
72
- task.spawn(callback, self.data, nil);
70
+ function Client:observe(key: (string | { string })?, callback: Observer)
71
+ if not key then
72
+ task.spawn(callback, self.data, nil);
73
+ return self._allSignal:Connect(callback);
74
+ end;
73
75
 
74
- return self._allSignal:Connect(callback);
75
- end;
76
+ local signalKey = Shared.getSignalKey(key);
77
+ if not self._signals[signalKey] then
78
+ self._signals[signalKey] = Signal.new();
79
+ end;
76
80
 
77
- if not self._signals[key] then
78
- self._signals[key] = Signal.new();
79
- end;
81
+ local initialValue = if typeof(key) == 'table' then Shared.getNestedValue(self.data, key) else self.data[key];
80
82
 
81
- task.spawn(callback, self.data[key], nil);
83
+ task.spawn(callback, initialValue, nil);
84
+ return self._signals[signalKey]:Connect(callback);
85
+ end;
82
86
 
83
- return self._signals[key]:Connect(callback);
87
+ function Client:_recursiveSignalCheck(currentPath: { string }, updateTree: any)
88
+ for k, v in updateTree do
89
+ local nextPath = table.clone(currentPath);
90
+ table.insert(nextPath, k);
91
+
92
+ local signalKey = Shared.getSignalKey(nextPath);
93
+ local signal = self._signals[signalKey];
94
+
95
+ if signal then
96
+ local newValue = Shared.getNestedValue(self.data, nextPath);
97
+ signal:Fire(newValue, newValue); -- Warning: Sends improper 'old' argument due to shallow copy optimization.
98
+ end;
99
+
100
+ if typeof(v) == 'table' then
101
+ self:_recursiveSignalCheck(nextPath, v)
102
+ end;
103
+ end;
84
104
  end;
85
105
 
86
106
  function Client:_applyUpdates(updates: Shared.GenericDataTable)
87
- local oldData = table.clone(self.data); -- Note: Shallow copy instead of deep copy.
88
-
89
- deepMergeAndApply(self.data, updates);
90
-
91
- local anyChanged = false;
92
-
93
- for key, newValue in updates do
94
- local oldValue = oldData[key];
95
-
96
- -- If it's a table, we assume it changed if it's in the update list.
97
- if typeof(newValue) == 'table' then
98
- anyChanged = true
99
- local signal = self._signals[key];
100
- if signal then
101
- signal:Fire(self.data[key], self.data[key]); -- Warning: Sends improper 'old' argument due to shallow copy optimization.
102
- end;
103
- elseif self.data[key] ~= oldValue then
104
- anyChanged = true;
105
- local signal = self._signals[key];
106
- if signal then
107
- signal:Fire(self.data[key], oldValue);
108
- end;
109
- end;
110
- end;
111
-
112
- if anyChanged then
113
- self._allSignal:Fire(self.data, updates);
114
- end;
107
+ local oldData = table.clone(self.data); -- Note: Shallow copy instead of deep copy.
108
+
109
+ deepMergeAndApply(self.data, updates);
110
+
111
+ local anyChanged = false;
112
+
113
+ for key, newValue in updates do
114
+ local oldValue = oldData[key];
115
+
116
+ -- If it's a table, we assume it changed if it's in the updates list.
117
+ if typeof(newValue) == 'table' then
118
+ anyChanged = true
119
+ local signal = self._signals[key];
120
+ if signal then
121
+ signal:Fire(self.data[key], self.data[key]); -- Warning: Sends improper 'old' argument due to shallow copy optimization.
122
+ end;
123
+
124
+ self:_recursiveSignalCheck({key}, newValue)
125
+ elseif self.data[key] ~= oldValue then
126
+ anyChanged = true;
127
+ local signal = self._signals[key];
128
+ if signal then
129
+ signal:Fire(self.data[key], oldValue);
130
+ end;
131
+ end;
132
+ end;
133
+
134
+ if anyChanged then
135
+ self._allSignal:Fire(self.data, updates);
136
+ end;
115
137
  end;
116
138
 
117
139
  function Client:destroy()
package/src/Server.lua CHANGED
@@ -99,46 +99,57 @@ function Server.new(config: ServerConfig)
99
99
  return self;
100
100
  end;
101
101
 
102
- function Server:observe(key: string?, callback: Observer)
103
- if not key then
104
- task.spawn(callback, self.data, nil);
105
- return self._allSignal:Connect(callback);
106
- end;
102
+ function Server:observe(key: (string | {string})?, callback: Observer)
103
+ if not key then
104
+ task.spawn(callback, self.data, nil);
105
+ return self._allSignal:Connect(callback);
106
+ end
107
107
 
108
- if not self._signals[key] then
109
- self._signals[key] = Signal.new();
110
- end;
108
+ local signalKey = Shared.getSignalKey(key);
109
+ if not self._signals[signalKey] then
110
+ self._signals[signalKey] = Signal.new();
111
+ end;
112
+
113
+ local initialValue = if typeof(key) == 'table' then Shared.getNestedValue(self.data, key) else self.data[key];
111
114
 
112
- task.spawn(callback, self.data[key], nil);
113
- return self._signals[key]:Connect(callback);
115
+ task.spawn(callback, initialValue, nil);
116
+ return self._signals[signalKey]:Connect(callback);
114
117
  end;
115
118
 
116
119
  function Server:set(key: string | {string}, value: any)
117
- if self._destroyed then return; end;
118
-
119
- local path = if typeof(key) == 'table' then key else {key};
120
- local topKey = path[1];
121
-
122
- local oldValue = Shared.getNestedValue(self.data, path);
123
- local newValue = if typeof(value) == 'function' then value(oldValue) else value;
124
- if oldValue == newValue then return; end;
125
-
126
- local oldTop = self.data[topKey];
127
-
128
- setNestedValue(self.data, path, newValue);
129
- queueNestedUpdate(self._queuedUpdates, path, newValue);
130
- self:_scheduleUpdatesFlush();
131
-
132
- do
133
- local signal = self._signals[topKey];
134
- if signal then
135
- signal:Fire(self.data[topKey], oldTop);
136
- end;
137
-
138
- local thisUpdate = {};
139
- setNestedValue(thisUpdate, path, newValue);
140
- self._allSignal:Fire(self.data, thisUpdate);
141
- end;
120
+ if self._destroyed then return; end;
121
+
122
+ local path = if typeof(key) == 'table' then key else {key};
123
+ local topKey = path[1];
124
+
125
+ local oldValue = Shared.getNestedValue(self.data, path);
126
+ local newValue = if typeof(value) == 'function' then value(oldValue) else value;
127
+ if oldValue == newValue then return; end;
128
+
129
+ local oldTop = self.data[topKey];
130
+
131
+ setNestedValue(self.data, path, newValue);
132
+ queueNestedUpdate(self._queuedUpdates, path, newValue);
133
+ self:_scheduleUpdatesFlush();
134
+
135
+ do
136
+ local topSignal = self._signals[topKey];
137
+ if topSignal then
138
+ topSignal:Fire(self.data[topKey], oldTop);
139
+ end;
140
+
141
+ local signalKey = Shared.getSignalKey(key);
142
+ if signalKey ~= topKey then
143
+ local pathSignal = self._signals[signalKey];
144
+ if pathSignal then
145
+ pathSignal:Fire(newValue, oldValue)
146
+ end;
147
+ end;
148
+
149
+ local thisUpdate = {};
150
+ setNestedValue(thisUpdate, path, newValue);
151
+ self._allSignal:Fire(self.data, thisUpdate);
152
+ end;
142
153
  end;
143
154
 
144
155
  function Server:get(key: (string | {string})?)
package/src/Shared.lua CHANGED
@@ -15,4 +15,9 @@ function Shared.getNestedValue(root: any, path: { string })
15
15
  return current;
16
16
  end;
17
17
 
18
+ function Shared.getSignalKey(key: string | {string})
19
+ if typeof(key) == 'string' then return key; end;
20
+ return table.concat(key, '\0');
21
+ end;
22
+
18
23
  return Shared;
package/src/index.d.ts CHANGED
@@ -17,6 +17,16 @@ declare namespace Replion {
17
17
  get<K extends keyof T>(key: K): T[K];
18
18
  get(path: string[]): any;
19
19
 
20
+ observe(key: undefined, callback: (newValue: T, oldValue: Partial<T>) => void): Connection;
21
+ observe<K extends keyof T>(
22
+ key: K,
23
+ callback: (newValue: T[K], oldValue: T[K] | undefined) => void,
24
+ ): Connection;
25
+ observe(
26
+ path: string[],
27
+ callback: (newValue: any, oldValue: any) => void,
28
+ ): Connection;
29
+
20
30
  destroy(): void;
21
31
  }
22
32
 
@@ -27,11 +37,15 @@ declare namespace Replion {
27
37
  get<K extends keyof T>(key: K): T[K];
28
38
  get(path: string[]): any;
29
39
 
30
- observe(key: undefined, callback: (newValue: T, oldValue: T | undefined) => void): Connection;
40
+ observe(key: undefined, callback: (newValue: T, oldValue: Partial<T>) => void): Connection;
31
41
  observe<K extends keyof T>(
32
42
  key: K,
33
43
  callback: (newValue: T[K], oldValue: T[K] | undefined) => void,
34
44
  ): Connection;
45
+ observe(
46
+ path: string[],
47
+ callback: (newValue: any, oldValue: any) => void,
48
+ ): Connection;
35
49
 
36
50
  destroy(): void;
37
51
  }