@rbxts/replion 1.0.15 → 1.0.16

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.15"`
5
+ `Replion = "shouxtech/replion@1.0.16"`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/replion",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "",
5
5
  "main": "src/init.lua",
6
6
  "scripts": {},
package/src/Client.lua CHANGED
@@ -5,6 +5,7 @@ local Shared = require(script.Parent.Shared);
5
5
  local Signal = require(isTypeScriptEnv and dependencies['sleitnick-signal'] or dependencies.Signal);
6
6
 
7
7
  type Observer = (newValue: any, oldValue: any) -> ();
8
+ type Deletion = { path: { string }, oldTable: any };
8
9
 
9
10
  local remote = script.Parent:WaitForChild(Shared.REMOTE_NAME) :: RemoteEvent;
10
11
 
@@ -80,7 +81,40 @@ function Client:observe(path: { string }?, callback: Observer)
80
81
  return self._signals[signalKey]:Connect(callback);
81
82
  end;
82
83
 
83
- function Client:_recursiveSignalCheck(currentPath: { string }, updateTree: any)
84
+ function Client:_collectDeletions(target: any, updates: any, path: { string }, out: { Deletion })
85
+ for k, v in updates do
86
+ local currentVal = target[k];
87
+ local newPath = table.clone(path);
88
+ table.insert(newPath, k);
89
+
90
+ if v == Shared.NIL_SENTINEL or (typeof(currentVal) == 'table' and typeof(v) ~= 'table') then
91
+ if typeof(currentVal) == 'table' then
92
+ table.insert(out, { path = newPath, oldTable = currentVal });
93
+ end;
94
+ elseif typeof(v) == 'table' and typeof(currentVal) == 'table' then
95
+ self:_collectDeletions(currentVal, v, newPath, out);
96
+ end;
97
+ end;
98
+ end;
99
+
100
+ function Client:_notifyDeepDeletion(path: { string }, oldTable: any)
101
+ for k, v in oldTable do
102
+ local nextPath = table.clone(path);
103
+ table.insert(nextPath, k);
104
+
105
+ local signalKey = Shared.getSignalKey(nextPath);
106
+ local signal = self._signals[signalKey];
107
+ if signal then
108
+ signal:Fire(nil, v);
109
+ end;
110
+
111
+ if typeof(v) == 'table' then
112
+ self:_notifyDeepDeletion(nextPath, v);
113
+ end;
114
+ end;
115
+ end;
116
+
117
+ function Client:_notifyRecursiveUpdates(currentPath: { string }, updateTree: any)
84
118
  for k, v in updateTree do
85
119
  local nextPath = table.clone(currentPath);
86
120
  table.insert(nextPath, k);
@@ -94,30 +128,36 @@ function Client:_recursiveSignalCheck(currentPath: { string }, updateTree: any)
94
128
  end;
95
129
 
96
130
  if typeof(v) == 'table' then
97
- self:_recursiveSignalCheck(nextPath, v);
131
+ self:_notifyRecursiveUpdates(nextPath, v);
98
132
  end;
99
133
  end;
100
134
  end;
101
135
 
102
136
  function Client:_applyUpdates(updates: Shared.GenericDataTable)
137
+ local deletions: { Deletion } = {};
138
+ self:_collectDeletions(self.data, updates, {}, deletions);
139
+
103
140
  local oldData = table.clone(self.data); -- Note: Shallow copy instead of deep copy.
104
141
 
105
142
  deepMergeAndApply(self.data, updates);
106
143
 
107
144
  local anyChanged = false;
108
145
 
146
+ for _, item in deletions do
147
+ self:_notifyDeepDeletion(item.path, item.oldTable);
148
+ end;
149
+
109
150
  for key, newValue in updates do
110
151
  local oldValue = oldData[key];
111
152
 
112
153
  -- If it's a table, we assume it changed if it's in the updates list.
113
154
  if typeof(newValue) == 'table' then
114
- anyChanged = true
155
+ anyChanged = true;
115
156
  local signal = self._signals[key];
116
157
  if signal then
117
158
  signal:Fire(self.data[key], self.data[key]); -- Warning: Sends improper 'old' argument due to shallow copy optimization.
118
159
  end;
119
-
120
- self:_recursiveSignalCheck({key}, newValue);
160
+ self:_notifyRecursiveUpdates({key}, newValue);
121
161
  elseif self.data[key] ~= oldValue then
122
162
  anyChanged = true;
123
163
  local signal = self._signals[key];
package/src/Server.lua CHANGED
@@ -116,21 +116,38 @@ function Server:observe(path: { string }?, callback: Observer)
116
116
  return self._signals[signalKey]:Connect(callback);
117
117
  end;
118
118
 
119
- function Server:_recursiveSignalCheck(currentPath: { string }, updateTree: any)
120
- for k, v in updateTree do
121
- local nextPath = table.clone(currentPath);
122
- table.insert(nextPath, k);
123
-
124
- local signalKey = Shared.getSignalKey(nextPath);
125
- local signal = self._signals[signalKey];
119
+ function Server:_notifyDeep(currentPath: { string }, newValue: any, oldValue: any)
120
+ if typeof(newValue) == 'table' then
121
+ for k, v in newValue do
122
+ local nextPath = table.clone(currentPath);
123
+ table.insert(nextPath, k);
124
+
125
+ local nextOld = if typeof(oldValue) == 'table' then oldValue[k] else nil;
126
+
127
+ local signalKey = Shared.getSignalKey(nextPath);
128
+ local signal = self._signals[signalKey];
129
+ if signal then
130
+ signal:Fire(v, nextOld);
131
+ end;
126
132
 
127
- if signal then
128
- local newValue = Shared.getNestedValue(self.data, nextPath);
129
- signal:Fire(newValue, newValue); -- Warning: Sends improper 'old' argument due to shallow copy optimization.
133
+ self:_notifyDeep(nextPath, v, nextOld);
130
134
  end;
135
+ end;
136
+
137
+ if typeof(oldValue) == 'table' then
138
+ for k, v in oldValue do
139
+ if typeof(newValue) == 'table' and newValue[k] ~= nil then continue; end;
140
+
141
+ local nextPath = table.clone(currentPath);
142
+ table.insert(nextPath, k);
131
143
 
132
- if typeof(v) == 'table' then
133
- self:_recursiveSignalCheck(nextPath, v);
144
+ local signalKey = Shared.getSignalKey(nextPath);
145
+ local signal = self._signals[signalKey];
146
+ if signal then
147
+ signal:Fire(nil, v);
148
+ end;
149
+
150
+ self:_notifyDeep(nextPath, nil, v);
134
151
  end;
135
152
  end;
136
153
  end;
@@ -163,10 +180,8 @@ function Server:set(path: { string }, value: any)
163
180
  pathSignal:Fire(newValue, oldValue)
164
181
  end;
165
182
  end;
166
-
167
- if typeof(newValue) == 'table' then
168
- self:_recursiveSignalCheck(path, newValue);
169
- end;
183
+
184
+ self:_notifyDeep(path, newValue, oldValue);
170
185
 
171
186
  local thisUpdate = {};
172
187
  setNestedValue(thisUpdate, path, newValue);