mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
- Introduced a new endpoint `/api/syncback` for one-click full sync from Roblox Studio to the filesystem, eliminating the need for an active WebSocket connection. - Implemented `SyncbackRequest` and `ServiceChunk` structures to handle service-level properties and child instances during syncback. - Enhanced `encodeService` to include ObjectValue carriers for accurate reference handling and prevent data loss. - Updated the syncback process to utilize Luau-style relative paths for reference attributes, improving path management and consistency. - Integrated session caching in the matching algorithm to optimize performance during syncback operations. These changes significantly improve the live syncback experience, ensuring reliable data synchronization and enhanced performance during development.
60 lines
2 KiB
Markdown
60 lines
2 KiB
Markdown
# Unsealed table assignment creates an optional property
|
|
|
|
**Status**: Implemented
|
|
|
|
## Summary
|
|
|
|
In Luau, tables have a state, which can, among others, be "unsealed".
|
|
An unsealed table is one that we are still constructing. Currently
|
|
assigning a table literal to an unsealed table does not introduce new
|
|
properties, so it is a type error if they are read.
|
|
We would like to change this so that assigning a table
|
|
literal to an unsealed table creates an optional property.
|
|
|
|
## Motivation
|
|
|
|
In lua-apps, there is testing code which (simplified) looks like:
|
|
|
|
```luau
|
|
local t = { u = {} }
|
|
t = { u = { p = 37 } }
|
|
t = { u = { q = "hi" } }
|
|
local x: number? = t.u.p
|
|
local y: string? = t.u.q
|
|
```
|
|
|
|
Currently, this code doesn't typecheck, due to `p` and `q` being unknown properties of `t.u`.
|
|
|
|
## Design
|
|
|
|
In order to support this idiom, we propose that assigning a table
|
|
to an unsealed table should add an optional property.
|
|
|
|
For example, before this change the type of `t` is `{ u: {} }`,
|
|
and after this change is `{ u: { p: number?, q: number? } }`.
|
|
|
|
This is implemented by adding a case to unification where the supertype
|
|
is an unsealed table, and the subtype is a table with extra properties.
|
|
Currently the extra properties are ignored, but with this change we would
|
|
add the property to the unsealed table (making it optional if necessary).
|
|
|
|
Since tables with optional properties of the same type are subtypes of
|
|
tables with indexers, this allows table literals to be used as dictionaries,
|
|
for example the type of `t` is a subtype of `{ u: { [string]: number } }`.
|
|
|
|
Note that we need to add an optional property, otherwise the example above will not typecheck.
|
|
```luau
|
|
local t = { u = {} }
|
|
t = { u = { p = 37 } }
|
|
t = { u = { q = "hi" } } -- fails because there's no u.p
|
|
```
|
|
|
|
## Drawbacks
|
|
|
|
The implementation of this proposal introduces optional types during unification,
|
|
and so needs access to an allocator.
|
|
|
|
## Alternatives
|
|
|
|
Rather than introducing optional properties, we could introduce an indexer. For example we could infer the type of
|
|
`t` as `{ u: { [string]: number } }`.
|