@trioforge/crucible 0.1.0 → 0.3.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.
Files changed (145) hide show
  1. package/maths/spline/package.json +4 -0
  2. package/out/client/index.d.ts +7 -0
  3. package/out/client/init.luau +36 -1
  4. package/out/configs.d.ts +37 -0
  5. package/out/configs.luau +46 -0
  6. package/out/data.d.ts +224 -0
  7. package/out/data.luau +97 -0
  8. package/out/emit/configs.d.ts +4 -0
  9. package/out/emit/configs.luau +22 -0
  10. package/out/emit/data.d.ts +6 -0
  11. package/out/emit/data.luau +19 -0
  12. package/out/emit/index.d.ts +5 -1
  13. package/out/emit/init.luau +23 -7
  14. package/out/emit/network.d.ts +6 -0
  15. package/out/emit/network.luau +36 -0
  16. package/out/emit/replicated.d.ts +4 -0
  17. package/out/emit/replicated.luau +13 -0
  18. package/out/index.d.ts +8 -0
  19. package/out/init.luau +23 -0
  20. package/out/internal/binding.luau +5 -0
  21. package/out/internal/boot.luau +112 -8
  22. package/out/internal/configs/limits.d.ts +10 -0
  23. package/out/internal/configs/limits.luau +25 -0
  24. package/out/internal/configs/port.d.ts +29 -0
  25. package/out/internal/configs/port.luau +99 -0
  26. package/out/internal/configs/runtime.d.ts +21 -0
  27. package/out/internal/configs/runtime.luau +981 -0
  28. package/out/internal/data/admission.d.ts +1 -0
  29. package/out/internal/data/admission.luau +673 -0
  30. package/out/internal/data/declarations.d.ts +1 -0
  31. package/out/internal/data/declarations.luau +384 -0
  32. package/out/internal/data/envelope.d.ts +1 -0
  33. package/out/internal/data/envelope.luau +318 -0
  34. package/out/internal/data/handles.d.ts +1 -0
  35. package/out/internal/data/handles.luau +255 -0
  36. package/out/internal/data/inbox-transforms.d.ts +1 -0
  37. package/out/internal/data/inbox-transforms.luau +458 -0
  38. package/out/internal/data/inbox.d.ts +1 -0
  39. package/out/internal/data/inbox.luau +437 -0
  40. package/out/internal/data/lease.d.ts +1 -0
  41. package/out/internal/data/lease.luau +304 -0
  42. package/out/internal/data/limits.d.ts +1 -0
  43. package/out/internal/data/limits.luau +234 -0
  44. package/out/internal/data/messages.d.ts +1 -0
  45. package/out/internal/data/messages.luau +69 -0
  46. package/out/internal/data/operation-id.d.ts +1 -0
  47. package/out/internal/data/operation-id.luau +61 -0
  48. package/out/internal/data/paths.d.ts +2 -0
  49. package/out/internal/data/paths.luau +323 -0
  50. package/out/internal/data/port.d.ts +1 -0
  51. package/out/internal/data/port.luau +290 -0
  52. package/out/internal/data/profiles.d.ts +1 -0
  53. package/out/internal/data/profiles.luau +862 -0
  54. package/out/internal/data/receipts.d.ts +1 -0
  55. package/out/internal/data/receipts.luau +190 -0
  56. package/out/internal/data/record-bindings.d.ts +1 -0
  57. package/out/internal/data/record-bindings.luau +92 -0
  58. package/out/internal/data/record-declarations.d.ts +1 -0
  59. package/out/internal/data/record-declarations.luau +140 -0
  60. package/out/internal/data/records.d.ts +1 -0
  61. package/out/internal/data/records.luau +400 -0
  62. package/out/internal/data/runtime.d.ts +1 -0
  63. package/out/internal/data/runtime.luau +918 -0
  64. package/out/internal/data/scheduler.d.ts +1 -0
  65. package/out/internal/data/scheduler.luau +507 -0
  66. package/out/internal/data/session.d.ts +1 -0
  67. package/out/internal/data/session.luau +234 -0
  68. package/out/internal/data/shutdown.d.ts +1 -0
  69. package/out/internal/data/shutdown.luau +91 -0
  70. package/out/internal/data/waiters.d.ts +1 -0
  71. package/out/internal/data/waiters.luau +65 -0
  72. package/out/internal/lifecycle.luau +45 -0
  73. package/out/internal/network/catalog.d.ts +26 -0
  74. package/out/internal/network/catalog.luau +182 -0
  75. package/out/internal/network/claims.d.ts +1 -0
  76. package/out/internal/network/claims.luau +146 -0
  77. package/out/internal/network/client-session.d.ts +1 -0
  78. package/out/internal/network/client-session.luau +405 -0
  79. package/out/internal/network/codec.d.ts +63 -0
  80. package/out/internal/network/codec.luau +1183 -0
  81. package/out/internal/network/envelope.d.ts +1 -0
  82. package/out/internal/network/envelope.luau +247 -0
  83. package/out/internal/network/limits.d.ts +26 -0
  84. package/out/internal/network/limits.luau +55 -0
  85. package/out/internal/network/port.d.ts +1 -0
  86. package/out/internal/network/port.luau +19 -0
  87. package/out/internal/network/roblox-network-port.d.ts +1 -0
  88. package/out/internal/network/roblox-network-port.luau +105 -0
  89. package/out/internal/network/schema.d.ts +72 -0
  90. package/out/internal/network/schema.luau +386 -0
  91. package/out/internal/network/server-session.d.ts +1 -0
  92. package/out/internal/network/server-session.luau +395 -0
  93. package/out/internal/network/session.d.ts +1 -0
  94. package/out/internal/network/session.luau +266 -0
  95. package/out/internal/reactive/context.d.ts +1 -0
  96. package/out/internal/reactive/context.luau +149 -0
  97. package/out/internal/reactive/flush.d.ts +1 -0
  98. package/out/internal/reactive/flush.luau +355 -0
  99. package/out/internal/reactive/graph.d.ts +1 -0
  100. package/out/internal/reactive/graph.luau +626 -0
  101. package/out/internal/reactive/limits.d.ts +1 -0
  102. package/out/internal/reactive/limits.luau +54 -0
  103. package/out/internal/reactive/ownership.d.ts +1 -0
  104. package/out/internal/reactive/ownership.luau +626 -0
  105. package/out/internal/registry.luau +10 -1
  106. package/out/internal/sync/client-sync.d.ts +1 -0
  107. package/out/internal/sync/client-sync.luau +157 -0
  108. package/out/internal/sync/declarations.d.ts +1 -0
  109. package/out/internal/sync/declarations.luau +276 -0
  110. package/out/internal/sync/frame.d.ts +1 -0
  111. package/out/internal/sync/frame.luau +91 -0
  112. package/out/internal/sync/server-sync.d.ts +1 -0
  113. package/out/internal/sync/server-sync.luau +502 -0
  114. package/out/internal/sync/values.d.ts +1 -0
  115. package/out/internal/sync/values.luau +930 -0
  116. package/out/maths/spline/curve.d.ts +35 -0
  117. package/out/maths/spline/curve.luau +1122 -0
  118. package/out/maths/spline/index.d.ts +2 -0
  119. package/out/maths/spline/init.luau +8 -0
  120. package/out/network.d.ts +66 -0
  121. package/out/network.luau +24 -0
  122. package/out/reactive.d.ts +76 -0
  123. package/out/reactive.luau +136 -0
  124. package/out/replicated.d.ts +38 -0
  125. package/out/replicated.luau +45 -0
  126. package/out/server/data.d.ts +54 -0
  127. package/out/server/data.luau +44 -0
  128. package/out/server/index.d.ts +17 -0
  129. package/out/server/init.luau +58 -4
  130. package/out/server/publish.d.ts +20 -0
  131. package/out/server/publish.luau +24 -0
  132. package/out/testing/index.d.ts +38 -0
  133. package/out/testing/init.luau +189 -0
  134. package/out/util/random/index.d.ts +24 -0
  135. package/out/util/random/init.luau +301 -0
  136. package/out/vide/index.d.ts +7 -0
  137. package/out/vide/init.luau +50 -0
  138. package/package.json +28 -2
  139. package/testing/package.json +4 -0
  140. package/transformer/data.cjs +72 -0
  141. package/transformer/declarations.cjs +153 -0
  142. package/transformer/index.js +87 -23
  143. package/transformer/network.cjs +961 -0
  144. package/util/random/package.json +4 -0
  145. package/vide/package.json +4 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,190 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local bootClock = TS.import(script, script.Parent.Parent, "boot").bootClock
4
+ local jsonBytes = TS.import(script, script.Parent, "envelope").jsonBytes
5
+ local _limits = TS.import(script, script.Parent, "limits")
6
+ local LOAD_DEADLINE_SECONDS = _limits.LOAD_DEADLINE_SECONDS
7
+ local MAX_PURCHASE_IDS = _limits.MAX_PURCHASE_IDS
8
+ local PURCHASE_ID_MAX_BYTES = _limits.PURCHASE_ID_MAX_BYTES
9
+ local RECEIPT_SAVE_TIMEOUT_SECONDS = _limits.RECEIPT_SAVE_TIMEOUT_SECONDS
10
+ local RECEIPTS_MAX_BYTES = _limits.RECEIPTS_MAX_BYTES
11
+ --* @internal The part of Roblox's receipt info that data reads.
12
+ --* @internal A developer product purchase, as a grant callback sees it.
13
+ --* @internal Stages an effect that runs once, after the grant is durable (rule 61).
14
+ --* @internal
15
+ --* @internal The profile store and grant callback that handle one developer product.
16
+ --* @internal MarketplaceService, as far as the router uses it.
17
+ --[[
18
+ *
19
+ * @internal Crucible's ProcessReceipt (rules 57 to 64). Idempotency rests on two facts: a purchase id and its grant's
20
+ * data change are one revision, and "granted" is returned only once an owned write with the session's token is
21
+ * confirmed to hold the id. Purchase ids are never evicted.
22
+
23
+ ]]
24
+ local ReceiptRouter
25
+ do
26
+ ReceiptRouter = setmetatable({}, {
27
+ __tostring = function()
28
+ return "ReceiptRouter"
29
+ end,
30
+ })
31
+ ReceiptRouter.__index = ReceiptRouter
32
+ function ReceiptRouter.new(...)
33
+ local self = setmetatable({}, ReceiptRouter)
34
+ return self:constructor(...) or self
35
+ end
36
+ function ReceiptRouter:constructor(engine)
37
+ self.engine = engine
38
+ self.routes = {}
39
+ self.closed = false
40
+ end
41
+ function ReceiptRouter:route(productId, route)
42
+ local _routes = self.routes
43
+ local _productId = productId
44
+ local _route = route
45
+ _routes[_productId] = _route
46
+ end
47
+ function ReceiptRouter:unroute(productId)
48
+ local _routes = self.routes
49
+ local _productId = productId
50
+ _routes[_productId] = nil
51
+ end
52
+ function ReceiptRouter:install(service)
53
+ self.service = service
54
+ service.ProcessReceipt = function(info)
55
+ return self:decision(self:process(info))
56
+ end
57
+ end
58
+ function ReceiptRouter:decision(result)
59
+ return if result == "granted" then Enum.ProductPurchaseDecision.PurchaseGranted else Enum.ProductPurchaseDecision.NotProcessedYet
60
+ end
61
+ function ReceiptRouter:close(retire)
62
+ if retire == nil then
63
+ retire = false
64
+ end
65
+ self.closed = true
66
+ if retire and self.service ~= nil then
67
+ self.service.ProcessReceipt = function()
68
+ return Enum.ProductPurchaseDecision.NotProcessedYet
69
+ end
70
+ end
71
+ end
72
+ function ReceiptRouter:process(info)
73
+ local engine = self.engine
74
+ local holdUntil = bootClock() + LOAD_DEADLINE_SECONDS
75
+ while true do
76
+ if self.closed then
77
+ return "notYet"
78
+ end
79
+ local _routes = self.routes
80
+ local _productId = info.ProductId
81
+ local route = _routes[_productId]
82
+ if route == nil then
83
+ engine:diagnose(`product:{info.ProductId}`, `a purchase of product {info.ProductId} was refused: no grant handles it`)
84
+ return "notYet"
85
+ end
86
+ local id = info.PurchaseId
87
+ if not (type(id) == "string") or #id < 1 or #id > PURCHASE_ID_MAX_BYTES then
88
+ engine:diagnose(`receipt-id:{info.ProductId}`, `a purchase of product {info.ProductId} was refused: its purchase id is not 1 to {PURCHASE_ID_MAX_BYTES} bytes`)
89
+ return "notYet"
90
+ end
91
+ local player = engine.port.players.byUserId(info.PlayerId)
92
+ if player == nil then
93
+ return "notYet"
94
+ end
95
+ local runtime = route.runtime
96
+ local session = runtime.sessions[player]
97
+ if session == nil or session.phase == 0 or session.sealedBy == "handoff" then
98
+ if bootClock() >= holdUntil then
99
+ return "notYet"
100
+ end
101
+ runtime.changed:park(holdUntil)
102
+ continue
103
+ end
104
+ if not runtime:writable(player) then
105
+ return "notYet"
106
+ end
107
+ if session.durable[id] ~= nil then
108
+ return self:granted(session, id)
109
+ end
110
+ return self:save(route, session, player, id, info)
111
+ end
112
+ end
113
+ function ReceiptRouter:save(route, session, player, id, info)
114
+ local runtime = route.runtime
115
+ local engine = self.engine
116
+ local _receipts = session.receipts
117
+ local _id = id
118
+ if not (table.find(_receipts, _id) ~= nil) then
119
+ if #session.receipts >= MAX_PURCHASE_IDS or jsonBytes(session.receipts) + jsonBytes(id) + 1 > RECEIPTS_MAX_BYTES then
120
+ engine:diagnose(`receipt-capacity:{session.token}`, `receipt capacity reached for {runtime.schema.name} {session.userId}`)
121
+ return "notYet"
122
+ end
123
+ local purchase = {
124
+ id = id,
125
+ productId = info.ProductId,
126
+ currencySpent = info.CurrencySpent,
127
+ }
128
+ local effects = {}
129
+ local afterGrant = function(effect)
130
+ local _effect = effect
131
+ if not (type(_effect) == "function") then
132
+ error("afterGrant takes a function", 2)
133
+ end
134
+ local _effect_1 = effect
135
+ table.insert(effects, _effect_1)
136
+ end
137
+ local ok = pcall(function()
138
+ return session:write(function(data)
139
+ return route.grant(player, data, purchase, afterGrant)
140
+ end, function()
141
+ session:stage(id)
142
+ local _effects = session.effects
143
+ local _id_1 = id
144
+ _effects[_id_1] = effects
145
+ end)
146
+ end)
147
+ if not ok then
148
+ engine:diagnose(`grant:{runtime.schema.name}:{info.ProductId}`, `{runtime.schema.name}: the grant for product {info.ProductId} threw, yielded or returned an invalid value; nothing was stored`)
149
+ return "notYet"
150
+ end
151
+ end
152
+ runtime:requestWrite(session, 2)
153
+ local timeout = bootClock() + RECEIPT_SAVE_TIMEOUT_SECONDS
154
+ while true do
155
+ local _durable = session.durable
156
+ local _id_1 = id
157
+ local _condition = not (_durable[_id_1] ~= nil)
158
+ if _condition then
159
+ _condition = session.phase ~= 3 and bootClock() < timeout and not engine.settled
160
+ end
161
+ if not _condition then
162
+ break
163
+ end
164
+ runtime.changed:park(timeout)
165
+ end
166
+ local _durable = session.durable
167
+ local _id_1 = id
168
+ return if _durable[_id_1] ~= nil then self:granted(session, id) else "notYet"
169
+ end
170
+ function ReceiptRouter:granted(session, id)
171
+ local _effects = session.effects
172
+ local _id = id
173
+ local effects = _effects[_id]
174
+ local _effects_1 = session.effects
175
+ local _id_1 = id
176
+ _effects_1[_id_1] = nil
177
+ for _, effect in effects or {} do
178
+ self.engine.port.spawn(function()
179
+ local ok = pcall(effect)
180
+ if not ok then
181
+ self.engine:diagnose(`effect:{session.token}:{id}`, `an afterGrant effect for {session.schema.name} {session.userId} threw`)
182
+ end
183
+ end)
184
+ end
185
+ return "granted"
186
+ end
187
+ end
188
+ return {
189
+ ReceiptRouter = ReceiptRouter,
190
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,92 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local bootClock = TS.import(script, script.Parent.Parent, "boot").bootClock
4
+ local CALL_DEADLINE_SECONDS = TS.import(script, script.Parent, "limits").CALL_DEADLINE_SECONDS
5
+ local dataPort = TS.import(script, script.Parent, "port").dataPort
6
+ local _record_declarations = TS.import(script, script.Parent, "record-declarations")
7
+ local declaredRecords = _record_declarations.declaredRecords
8
+ local installRecordDriver = _record_declarations.installRecordDriver
9
+ local RecordStore = TS.import(script, script.Parent, "records").RecordStore
10
+ local Waiters = TS.import(script, script.Parent, "waiters").Waiters
11
+ local bound = {}
12
+ local activation
13
+ --* @internal Rule 104: gives every declared record store its engine, and wakes calls waiting for activation.
14
+ local function bindRecords(engine)
15
+ for name, declaration in declaredRecords() do
16
+ local _recordStore = RecordStore.new(engine, declaration.schema)
17
+ bound[name] = _recordStore
18
+ end
19
+ local _result = activation
20
+ if _result ~= nil then
21
+ _result:wake()
22
+ end
23
+ end
24
+ --* @internal
25
+ local function unbindRecords()
26
+ table.clear(bound)
27
+ end
28
+ --* Rule 4: before activation a call waits for it, within its own deadline.
29
+ local function activated(name)
30
+ local deadline = bootClock() + CALL_DEADLINE_SECONDS
31
+ while true do
32
+ local _name = name
33
+ local _condition = bound[_name] == nil
34
+ if _condition then
35
+ _condition = bootClock() < deadline
36
+ end
37
+ if not _condition then
38
+ break
39
+ end
40
+ if activation == nil then
41
+ activation = Waiters.new(dataPort())
42
+ end
43
+ activation:park(deadline)
44
+ end
45
+ local _name = name
46
+ return bound[_name]
47
+ end
48
+ local function publicResult(result)
49
+ return if result.kind == "ok" then {
50
+ ok = true,
51
+ value = result.value,
52
+ } else {
53
+ ok = false,
54
+ reason = result.kind,
55
+ }
56
+ end
57
+ local function publicUpdate(result)
58
+ return if result.kind == "ok" then {
59
+ ok = true,
60
+ value = result.value,
61
+ replayed = result.replayed,
62
+ } else {
63
+ ok = false,
64
+ reason = result.kind,
65
+ }
66
+ end
67
+ installRecordDriver({
68
+ read = function(self, name, key)
69
+ local store = activated(name)
70
+ if store == nil then
71
+ return {
72
+ ok = false,
73
+ reason = "timeout",
74
+ }
75
+ end
76
+ return publicResult(store:read(key))
77
+ end,
78
+ update = function(self, name, key, change, id)
79
+ local store = activated(name)
80
+ if store == nil then
81
+ return {
82
+ ok = false,
83
+ reason = "timeout",
84
+ }
85
+ end
86
+ return publicUpdate(store:update(key, change, id))
87
+ end,
88
+ })
89
+ return {
90
+ bindRecords = bindRecords,
91
+ unbindRecords = unbindRecords,
92
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,140 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local sealSchema = TS.import(script, script.Parent, "admission").sealSchema
4
+ local _limits = TS.import(script, script.Parent, "limits")
5
+ local MAX_DATA_DECLARATIONS = _limits.MAX_DATA_DECLARATIONS
6
+ local STORE_NAME_MAX_BYTES = _limits.STORE_NAME_MAX_BYTES
7
+ --* @internal
8
+ --[[
9
+ *
10
+ * @internal What a declared store's calls run on once DataRuntime activates. This module is reached from the emit
11
+ * entry, so it imports nothing that loads boot; `record-bindings.ts` installs the driver.
12
+
13
+ ]]
14
+ local declarations = {}
15
+ local sealed = false
16
+ local driver
17
+ local profiles = {}
18
+ --* @internal Rule 2: profile and generic stores share one index of store names.
19
+ local function storeNameTaken(name)
20
+ local _name = name
21
+ local _condition = declarations[_name] ~= nil
22
+ if not _condition then
23
+ local _name_1 = name
24
+ _condition = profiles[_name_1] ~= nil
25
+ end
26
+ return _condition
27
+ end
28
+ --* @internal Rule 3: every data declaration in this realm counts toward MAX_DATA_DECLARATIONS.
29
+ local function dataDeclarationCount()
30
+ -- ▼ ReadonlyMap.size ▼
31
+ local _size = 0
32
+ for _ in declarations do
33
+ _size += 1
34
+ end
35
+ -- ▲ ReadonlyMap.size ▲
36
+ -- ▼ ReadonlySet.size ▼
37
+ local _size_1 = 0
38
+ for _ in profiles do
39
+ _size_1 += 1
40
+ end
41
+ -- ▲ ReadonlySet.size ▲
42
+ return _size + _size_1
43
+ end
44
+ --* @internal
45
+ local function registerProfileName(name)
46
+ local _name = name
47
+ profiles[_name] = true
48
+ end
49
+ --* @internal True after DataRuntime constructed (rule 3).
50
+ local function dataRegistrySealed()
51
+ return sealed
52
+ end
53
+ --* @internal Rule 2's grammar: dot-separated `[A-Za-z][A-Za-z0-9_]*` segments, with `Crucible` reserved as the first.
54
+ local function checkStoreName(name)
55
+ if #name == 0 or #name > STORE_NAME_MAX_BYTES then
56
+ error(`{name}: a store name is 1 to {STORE_NAME_MAX_BYTES} bytes`, 4)
57
+ end
58
+ local segments = string.split(name, ".")
59
+ for _, segment in segments do
60
+ if (string.match(segment, "^[A-Za-z][A-Za-z0-9_]*$")) == nil then
61
+ error(`{name}: a store name is dot-separated segments of letters, digits and underscores`, 4)
62
+ end
63
+ end
64
+ if segments[1] == "Crucible" then
65
+ error(`{name}: the name Crucible is reserved`, 4)
66
+ end
67
+ end
68
+ --* @internal Rule 3: DataRuntime seals the registry when it constructs; a failed boot unseals it.
69
+ local function sealDeclarations(value)
70
+ sealed = value
71
+ end
72
+ --* @internal The declarations a DataRuntime binds at activation (rule 104).
73
+ local function declaredRecords()
74
+ return declarations
75
+ end
76
+ --* @internal
77
+ local function installRecordDriver(value)
78
+ driver = value
79
+ end
80
+ local function installed(name)
81
+ if driver == nil then
82
+ error(`{name}: the data runtime is not loaded; import @trioforge/crucible/server`, 3)
83
+ end
84
+ return driver
85
+ end
86
+ --[[
87
+ *
88
+ * @internal Rules 4 and 85: the emit form's body. Admits and freezes `defaults` with `value`, registers the name, and
89
+ * returns a frozen handle whose two calls bind to the engine at activation.
90
+
91
+ ]]
92
+ local function declareRecords(name, defaults, migrations, value)
93
+ checkStoreName(name)
94
+ if sealed then
95
+ error(`{name} was declared after the data registry sealed; declare stores in modules that boot loads`, 3)
96
+ end
97
+ if storeNameTaken(name) then
98
+ error(`{name} is already declared`, 3)
99
+ end
100
+ if dataDeclarationCount() >= MAX_DATA_DECLARATIONS then
101
+ error(`{name}: more than {MAX_DATA_DECLARATIONS} data declarations`, 3)
102
+ end
103
+ local _array = {}
104
+ local _length = #_array
105
+ local _array_1 = (migrations or {})
106
+ table.move(_array_1, 1, #_array_1, _length + 1, _array)
107
+ local steps = _array
108
+ local schema = sealSchema({
109
+ name = name,
110
+ version = #steps,
111
+ defaults = defaults,
112
+ node = value,
113
+ migrations = steps,
114
+ })
115
+ local _name = name
116
+ local _arg1 = {
117
+ name = name,
118
+ schema = schema,
119
+ }
120
+ declarations[_name] = _arg1
121
+ return table.freeze({
122
+ read = function(self, key)
123
+ return installed(name):read(name, key)
124
+ end,
125
+ update = function(self, key, change, id)
126
+ return installed(name):update(name, key, change, id)
127
+ end,
128
+ })
129
+ end
130
+ return {
131
+ storeNameTaken = storeNameTaken,
132
+ dataDeclarationCount = dataDeclarationCount,
133
+ registerProfileName = registerProfileName,
134
+ dataRegistrySealed = dataRegistrySealed,
135
+ checkStoreName = checkStoreName,
136
+ sealDeclarations = sealDeclarations,
137
+ declaredRecords = declaredRecords,
138
+ installRecordDriver = installRecordDriver,
139
+ declareRecords = declareRecords,
140
+ }
@@ -0,0 +1 @@
1
+ export {};