@trioforge/crucible 0.0.0-stage → 0.1.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/client/package.json +4 -0
  3. package/emit/package.json +4 -0
  4. package/out/all.d.ts +7 -0
  5. package/out/all.luau +2 -0
  6. package/out/attribute.d.ts +7 -0
  7. package/out/attribute.luau +7 -0
  8. package/out/client/index.d.ts +3 -0
  9. package/out/client/init.luau +20 -0
  10. package/out/crucible-behaviour.d.ts +16 -0
  11. package/out/crucible-behaviour.luau +78 -0
  12. package/out/crucible-object.d.ts +10 -0
  13. package/out/crucible-object.luau +69 -0
  14. package/out/emit/index.d.ts +41 -0
  15. package/out/emit/init.luau +85 -0
  16. package/out/index.d.ts +12 -0
  17. package/out/init.luau +11 -0
  18. package/out/inject.d.ts +1 -0
  19. package/out/inject.luau +7 -0
  20. package/out/internal/binding.d.ts +1 -0
  21. package/out/internal/binding.luau +610 -0
  22. package/out/internal/boot.d.ts +1 -0
  23. package/out/internal/boot.luau +463 -0
  24. package/out/internal/construction-claim.d.ts +1 -0
  25. package/out/internal/construction-claim.luau +26 -0
  26. package/out/internal/dense-list.d.ts +1 -0
  27. package/out/internal/dense-list.luau +155 -0
  28. package/out/internal/diagnostics.d.ts +1 -0
  29. package/out/internal/diagnostics.luau +29 -0
  30. package/out/internal/hooks.d.ts +1 -0
  31. package/out/internal/hooks.luau +53 -0
  32. package/out/internal/implementers.d.ts +1 -0
  33. package/out/internal/implementers.luau +119 -0
  34. package/out/internal/lifecycle.d.ts +1 -0
  35. package/out/internal/lifecycle.luau +867 -0
  36. package/out/internal/log-output.d.ts +1 -0
  37. package/out/internal/log-output.luau +106 -0
  38. package/out/internal/port.d.ts +1 -0
  39. package/out/internal/port.luau +12 -0
  40. package/out/internal/registry.d.ts +1 -0
  41. package/out/internal/registry.luau +446 -0
  42. package/out/internal/roblox-port.d.ts +1 -0
  43. package/out/internal/roblox-port.luau +117 -0
  44. package/out/internal/runner.d.ts +1 -0
  45. package/out/internal/runner.luau +86 -0
  46. package/out/internal/scheduler.d.ts +1 -0
  47. package/out/internal/scheduler.luau +207 -0
  48. package/out/internal/state.d.ts +1 -0
  49. package/out/internal/state.luau +41 -0
  50. package/out/log-level.d.ts +7 -0
  51. package/out/log-level.luau +21 -0
  52. package/out/logging.d.ts +34 -0
  53. package/out/logging.luau +233 -0
  54. package/out/server/index.d.ts +2 -0
  55. package/out/server/init.luau +16 -0
  56. package/out/subsystem.d.ts +4 -0
  57. package/out/subsystem.luau +30 -0
  58. package/package.json +41 -5
  59. package/server/package.json +4 -0
  60. package/transformer/diagnostics.cjs +19 -0
  61. package/transformer/index.js +715 -0
  62. package/transformer/type-id.cjs +80 -0
  63. package/README.md +0 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Trio Forge Studio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../out/client/init.luau",
3
+ "types": "../out/client/index.d.ts"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../out/emit/init.luau",
3
+ "types": "../out/emit/index.d.ts"
4
+ }
package/out/all.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export interface All<T extends object> {
2
+ size(): number;
3
+ has(item: T): boolean;
4
+ first(): T | undefined;
5
+ forEach(visit: (item: T) => void): void;
6
+ observe(added: (item: T) => void, removed?: (item: T) => void): () => void;
7
+ }
package/out/all.luau ADDED
@@ -0,0 +1,2 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ return nil
@@ -0,0 +1,7 @@
1
+ type AttributeValue = string | number | boolean | Vector3 | Color3;
2
+ export declare function attribute<T extends AttributeValue>(): T;
3
+ export declare function attribute(fallback: number): number;
4
+ export declare function attribute(fallback: string): string;
5
+ export declare function attribute(fallback: boolean): boolean;
6
+ export declare function attribute<T extends AttributeValue | undefined>(fallback: T): T;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local function attribute(_fallback)
3
+ error("attribute() was not replaced; add the Crucible transformer to the compiler plugins")
4
+ end
5
+ return {
6
+ attribute = attribute,
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { BootOptions } from "../index";
2
+ export declare const BOOTED_ATTRIBUTE = "CrucibleBooted";
3
+ export declare function boot(options: BootOptions): void;
@@ -0,0 +1,20 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local bootSide = TS.import(script, script.Parent, "internal", "boot").boot
4
+ if not game:GetService("RunService"):IsClient() then
5
+ error("@trioforge/crucible/client loaded on the server")
6
+ end
7
+ local BOOTED_ATTRIBUTE = "CrucibleBooted"
8
+ local function boot(options)
9
+ bootSide({
10
+ name = "client",
11
+ renders = true,
12
+ booted = function()
13
+ return game:GetService("Players").LocalPlayer:SetAttribute(BOOTED_ATTRIBUTE, true)
14
+ end,
15
+ }, options)
16
+ end
17
+ return {
18
+ boot = boot,
19
+ BOOTED_ATTRIBUTE = BOOTED_ATTRIBUTE,
20
+ }
@@ -0,0 +1,16 @@
1
+ import { CrucibleObject } from "./crucible-object";
2
+ export type BehaviourClass<T extends CrucibleBehaviour<string>> = new (...args: never[]) => T;
3
+ export declare abstract class CrucibleBehaviour<Tag extends string, I extends Instance = Instance> extends CrucibleObject {
4
+ static accepts(instance: Instance): boolean;
5
+ static refresh(instance: Instance): void;
6
+ static get<T extends CrucibleBehaviour<string>>(this: BehaviourClass<T>, instance: Instance): T | undefined;
7
+ readonly instance: I;
8
+ readonly tag: Tag;
9
+ constructor();
10
+ isEnabled(): boolean;
11
+ setEnabled(enabled: boolean): void;
12
+ remove(): void;
13
+ protected onEnable(): void;
14
+ protected onDisable(): void;
15
+ protected onDestroy(): void;
16
+ }
@@ -0,0 +1,78 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local CrucibleObject = TS.import(script, script.Parent, "crucible-object").CrucibleObject
4
+ local _binding = TS.import(script, script.Parent, "internal", "binding")
5
+ local boundTo = _binding.boundTo
6
+ local defaultAccepts = _binding.defaultAccepts
7
+ local refresh = _binding.refresh
8
+ local remove = _binding.remove
9
+ local readClaim = TS.import(script, script.Parent, "internal", "construction-claim").readClaim
10
+ local installBehaviourHooks = TS.import(script, script.Parent, "internal", "hooks").installBehaviourHooks
11
+ local _lifecycle = TS.import(script, script.Parent, "internal", "lifecycle")
12
+ local isLive = _lifecycle.isLive
13
+ local request = _lifecycle.request
14
+ local stateOf = _lifecycle.stateOf
15
+ local CrucibleBehaviour
16
+ do
17
+ local super = CrucibleObject
18
+ CrucibleBehaviour = setmetatable({}, {
19
+ __tostring = function()
20
+ return "CrucibleBehaviour"
21
+ end,
22
+ __index = super,
23
+ })
24
+ CrucibleBehaviour.__index = CrucibleBehaviour
25
+ function CrucibleBehaviour:constructor()
26
+ super.constructor(self)
27
+ local state = readClaim() or error("CrucibleBehaviour constructed outside Crucible")
28
+ self.instance = state.instance
29
+ end
30
+ function CrucibleBehaviour:accepts(instance)
31
+ return defaultAccepts(instance)
32
+ end
33
+ function CrucibleBehaviour:refresh(instance)
34
+ refresh(instance)
35
+ end
36
+ function CrucibleBehaviour:get(instance)
37
+ local state = boundTo(self, instance)
38
+ return if state ~= nil and isLive(state) then (state.object) else nil
39
+ end
40
+ function CrucibleBehaviour:isEnabled()
41
+ local state = stateOf(self)
42
+ return state ~= nil and state.phase == 3 and isLive(state)
43
+ end
44
+ function CrucibleBehaviour:setEnabled(enabled)
45
+ local state = stateOf(self)
46
+ if state ~= nil then
47
+ request(state, if enabled then 0 else 1)
48
+ end
49
+ end
50
+ function CrucibleBehaviour:remove()
51
+ local state = stateOf(self)
52
+ if state ~= nil then
53
+ remove(state)
54
+ end
55
+ end
56
+ function CrucibleBehaviour:onEnable()
57
+ end
58
+ function CrucibleBehaviour:onDisable()
59
+ end
60
+ function CrucibleBehaviour:onDestroy()
61
+ end
62
+ do
63
+ installBehaviourHooks({
64
+ onEnable = function(b)
65
+ return b:onEnable()
66
+ end,
67
+ onDisable = function(b)
68
+ return b:onDisable()
69
+ end,
70
+ onDestroy = function(b)
71
+ return b:onDestroy()
72
+ end,
73
+ })
74
+ end
75
+ end
76
+ return {
77
+ CrucibleBehaviour = CrucibleBehaviour,
78
+ }
@@ -0,0 +1,10 @@
1
+ export declare abstract class CrucibleObject {
2
+ static readonly renderPriority?: number;
3
+ constructor();
4
+ protected awake(): void;
5
+ protected start(): void;
6
+ protected fixedUpdate(_dt: number): void;
7
+ protected update(_dt: number): void;
8
+ protected lateUpdate(_dt: number): void;
9
+ protected preRender(_dt: number): void;
10
+ }
@@ -0,0 +1,69 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local readClaim = TS.import(script, script.Parent, "internal", "construction-claim").readClaim
4
+ local _hooks = TS.import(script, script.Parent, "internal", "hooks")
5
+ local FRAME_HOOK_NAMES = _hooks.FRAME_HOOK_NAMES
6
+ local installObjectHooks = _hooks.installObjectHooks
7
+ local CrucibleObject
8
+ do
9
+ CrucibleObject = {}
10
+ function CrucibleObject:constructor()
11
+ local state = readClaim() or error("CrucibleObject constructed outside Crucible")
12
+ state.object = self
13
+ end
14
+ function CrucibleObject:awake()
15
+ end
16
+ function CrucibleObject:start()
17
+ end
18
+ function CrucibleObject:fixedUpdate(_dt)
19
+ end
20
+ function CrucibleObject:update(_dt)
21
+ end
22
+ function CrucibleObject:lateUpdate(_dt)
23
+ end
24
+ function CrucibleObject:preRender(_dt)
25
+ end
26
+ do
27
+ installObjectHooks({
28
+ awake = function(o)
29
+ return o:awake()
30
+ end,
31
+ start = function(o)
32
+ return o:start()
33
+ end,
34
+ frame = {
35
+ [0] = function(o, dt)
36
+ return o:preRender(dt)
37
+ end,
38
+ [1] = function(o, dt)
39
+ return o:fixedUpdate(dt)
40
+ end,
41
+ [2] = function(o, dt)
42
+ return o:update(dt)
43
+ end,
44
+ [3] = function(o, dt)
45
+ return o:lateUpdate(dt)
46
+ end,
47
+ },
48
+ overrides = function(klass)
49
+ local methods = klass
50
+ local defaults = CrucibleObject
51
+ local mask = 0
52
+ -- ▼ ReadonlyArray.forEach ▼
53
+ local _callback = function(name, hook)
54
+ if methods[name] ~= defaults[name] then
55
+ mask = bit32.bor(mask, bit32.lshift(1, hook))
56
+ end
57
+ end
58
+ for _k, _v in FRAME_HOOK_NAMES do
59
+ _callback(_v, _k - 1, FRAME_HOOK_NAMES)
60
+ end
61
+ -- ▲ ReadonlyArray.forEach ▲
62
+ return mask
63
+ end,
64
+ })
65
+ end
66
+ end
67
+ return {
68
+ CrucibleObject = CrucibleObject,
69
+ }
@@ -0,0 +1,41 @@
1
+ import type { All } from "../all";
2
+ import type { CrucibleObject } from "../crucible-object";
3
+ export type EmittedDep = string | {
4
+ readonly all: string;
5
+ };
6
+ interface EmittedBase {
7
+ readonly id: string;
8
+ readonly deps: readonly EmittedDep[];
9
+ readonly provides: readonly string[];
10
+ }
11
+ export type EmittedClass = (EmittedBase & {
12
+ readonly kind: "subsystem";
13
+ }) | (EmittedBase & {
14
+ readonly kind: "behaviour";
15
+ readonly tag: string;
16
+ readonly instance: readonly (keyof Instances)[];
17
+ readonly attributes?: {
18
+ readonly [field: string]: EmittedAttribute;
19
+ };
20
+ });
21
+ export type Check = (value: unknown) => boolean;
22
+ export declare function defineClass(klass: new (...args: never[]) => CrucibleObject, emitted: EmittedClass): void;
23
+ export declare function resolve<T extends object>(id: string): T;
24
+ export declare function resolveAll<T extends object>(id: string): All<T>;
25
+ export declare const t: {
26
+ readonly string: Check;
27
+ readonly number: Check;
28
+ readonly boolean: Check;
29
+ readonly vector3: Check;
30
+ readonly color3: Check;
31
+ readonly literal: (expected: string | number | boolean) => Check;
32
+ readonly optional: (check: Check) => Check;
33
+ readonly union: (...checks: Check[]) => Check;
34
+ };
35
+ export interface EmittedAttribute {
36
+ readonly name: string;
37
+ readonly check: Check;
38
+ readonly required: boolean;
39
+ }
40
+ export declare function attribute<T>(object: object, field: string, fallback?: T): T;
41
+ export {};
@@ -0,0 +1,85 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local readClaim = TS.import(script, script.Parent, "internal", "construction-claim").readClaim
4
+ local _registry = TS.import(script, script.Parent, "internal", "registry")
5
+ local define = _registry.define
6
+ local resolveOne = _registry.resolveOne
7
+ local setFor = _registry.setFor
8
+ local function defineClass(klass, emitted)
9
+ define(klass, emitted)
10
+ end
11
+ local function resolve(id)
12
+ return resolveOne(id)
13
+ end
14
+ local function resolveAll(id)
15
+ return setFor(id)
16
+ end
17
+ local t = {
18
+ string = (function(value)
19
+ local _value = value
20
+ return type(_value) == "string"
21
+ end),
22
+ number = (function(value)
23
+ local _value = value
24
+ return type(_value) == "number"
25
+ end),
26
+ boolean = (function(value)
27
+ local _value = value
28
+ return type(_value) == "boolean"
29
+ end),
30
+ vector3 = (function(value)
31
+ local _value = value
32
+ return typeof(_value) == "Vector3"
33
+ end),
34
+ color3 = (function(value)
35
+ local _value = value
36
+ return typeof(_value) == "Color3"
37
+ end),
38
+ literal = function(expected)
39
+ return function(value)
40
+ return value == expected
41
+ end
42
+ end,
43
+ optional = function(check)
44
+ return function(value)
45
+ return value == nil or check(value)
46
+ end
47
+ end,
48
+ union = function(...)
49
+ local checks = { ... }
50
+ return function(value)
51
+ -- ▼ ReadonlyArray.some ▼
52
+ local _result = false
53
+ local _callback = function(check)
54
+ return check(value)
55
+ end
56
+ for _k, _v in checks do
57
+ if _callback(_v, _k - 1, checks) then
58
+ _result = true
59
+ break
60
+ end
61
+ end
62
+ -- ▲ ReadonlyArray.some ▲
63
+ return _result
64
+ end
65
+ end,
66
+ }
67
+ local function attribute(object, field, fallback)
68
+ local claim = readClaim()
69
+ if claim == nil or claim.object ~= object then
70
+ error("attribute read outside construction claim")
71
+ end
72
+ local _value = claim.attributes
73
+ if _value ~= nil then
74
+ _value = _value[field]
75
+ end
76
+ local value = _value
77
+ return if value == nil then fallback else value
78
+ end
79
+ return {
80
+ defineClass = defineClass,
81
+ resolve = resolve,
82
+ resolveAll = resolveAll,
83
+ attribute = attribute,
84
+ t = t,
85
+ }
package/out/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export { Subsystem } from "./subsystem";
2
+ export type { CrucibleObject } from "./crucible-object";
3
+ export type { All } from "./all";
4
+ export { inject } from "./inject";
5
+ export { attribute } from "./attribute";
6
+ export { CrucibleBehaviour, type BehaviourClass } from "./crucible-behaviour";
7
+ export interface BootOptions {
8
+ readonly load: readonly string[];
9
+ readonly fixedRate?: number;
10
+ }
11
+ export { Logging, LogLevel } from "./logging";
12
+ export type { Logger, LogRecord, LogSink, SinkSubscription, LogContext, LogProperties } from "./logging";
package/out/init.luau ADDED
@@ -0,0 +1,11 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local exports = {}
4
+ exports.Subsystem = TS.import(script, script, "subsystem").Subsystem
5
+ exports.inject = TS.import(script, script, "inject").inject
6
+ exports.attribute = TS.import(script, script, "attribute").attribute
7
+ exports.CrucibleBehaviour = TS.import(script, script, "crucible-behaviour").CrucibleBehaviour
8
+ local _logging = TS.import(script, script, "logging")
9
+ exports.Logging = _logging.Logging
10
+ exports.LogLevel = _logging.LogLevel
11
+ return exports
@@ -0,0 +1 @@
1
+ export declare function inject<T extends object>(): T;
@@ -0,0 +1,7 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local function inject()
3
+ error("inject<T>() was not replaced; add the Crucible transformer to the compiler plugins")
4
+ end
5
+ return {
6
+ inject = inject,
7
+ }
@@ -0,0 +1 @@
1
+ export {};