browsermesh-kernel 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.
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Kernel constants — frozen defaults, capability tags, and error codes.
3
+ *
4
+ * Defines shared configuration values, capability tags for tenant access
5
+ * control, and machine-readable error codes used throughout the kernel.
6
+ * All objects are frozen to prevent runtime mutation.
7
+ *
8
+ * @module constants
9
+ */
10
+
11
+ /**
12
+ * Default configuration values used across the kernel.
13
+ *
14
+ * @property {number} MAX_RESOURCE_TABLE_SIZE - Maximum entries in a ResourceTable.
15
+ * @property {number} DEFAULT_STREAM_BUFFER_SIZE - Default highWaterMark for ByteStream pipes.
16
+ * @property {number} DEFAULT_TRACER_CAPACITY - Default ring buffer size for Tracer events.
17
+ * @property {number} DEFAULT_LOGGER_CAPACITY - Default ring buffer size for Logger entries.
18
+ */
19
+ export const KERNEL_DEFAULTS = Object.freeze({
20
+ MAX_RESOURCE_TABLE_SIZE: 4096,
21
+ DEFAULT_STREAM_BUFFER_SIZE: 1024,
22
+ DEFAULT_TRACER_CAPACITY: 1024,
23
+ DEFAULT_LOGGER_CAPACITY: 1024,
24
+ });
25
+
26
+ /**
27
+ * Capability tags for tenant access control.
28
+ *
29
+ * Each tag grants access to a kernel subsystem. Pass these to
30
+ * {@link Kernel#createTenant} in the `capabilities` array.
31
+ *
32
+ * @property {string} NET - Access to networking subsystems (`'net'`).
33
+ * @property {string} FS - Access to filesystem operations (`'fs'`).
34
+ * @property {string} CLOCK - Access to clock/time primitives (`'clock'`).
35
+ * @property {string} RNG - Access to random number generation (`'rng'`).
36
+ * @property {string} IPC - Access to inter-process communication (`'ipc'`).
37
+ * @property {string} STDIO - Access to standard I/O streams (`'stdio'`).
38
+ * @property {string} TRACE - Access to the tracing subsystem (`'trace'`).
39
+ * @property {string} CHAOS - Access to chaos engineering controls (`'chaos'`).
40
+ * @property {string} ENV - Access to environment variables (`'env'`).
41
+ * @property {string} SIGNAL - Access to signal handling (`'signal'`).
42
+ * @property {string} MESH - Access to mesh networking and P2P operations (`'mesh'`).
43
+ * @property {string} PAYMENT - Access to payment channels and credit ledgers (`'payment'`).
44
+ * @property {string} CONSENSUS - Access to voting and consensus protocols (`'consensus'`).
45
+ * @property {string} ALL - Wildcard granting all capabilities (`'*'`).
46
+ */
47
+ export const KERNEL_CAP = Object.freeze({
48
+ NET: 'net',
49
+ FS: 'fs',
50
+ CLOCK: 'clock',
51
+ RNG: 'rng',
52
+ IPC: 'ipc',
53
+ STDIO: 'stdio',
54
+ TRACE: 'trace',
55
+ CHAOS: 'chaos',
56
+ ENV: 'env',
57
+ SIGNAL: 'signal',
58
+ MESH: 'mesh',
59
+ PAYMENT: 'payment',
60
+ CONSENSUS: 'consensus',
61
+ ALL: '*',
62
+ });
63
+
64
+ /**
65
+ * Machine-readable error codes used by kernel error classes.
66
+ *
67
+ * @property {string} ENOHANDLE - Resource handle not found in table.
68
+ * @property {string} EHANDLETYPE - Resource handle exists but type mismatch.
69
+ * @property {string} ETABLEFULL - Resource table at maximum capacity.
70
+ * @property {string} ESTREAMCLOSED - Operation on a closed ByteStream.
71
+ * @property {string} ECAPDENIED - Capability not granted to tenant.
72
+ * @property {string} EALREADY - Name or resource already registered.
73
+ * @property {string} ENOTFOUND - Named resource not found.
74
+ * @property {string} ESIGNAL - Operation interrupted by signal.
75
+ */
76
+ export const KERNEL_ERROR = Object.freeze({
77
+ ENOHANDLE: 'ENOHANDLE',
78
+ EHANDLETYPE: 'EHANDLETYPE',
79
+ ETABLEFULL: 'ETABLEFULL',
80
+ ESTREAMCLOSED: 'ESTREAMCLOSED',
81
+ ECAPDENIED: 'ECAPDENIED',
82
+ EALREADY: 'EALREADY',
83
+ ENOTFOUND: 'ENOTFOUND',
84
+ ESIGNAL: 'ESIGNAL',
85
+ });
package/src/env.mjs ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Environment — per-tenant immutable key-value environment.
3
+ *
4
+ * Once constructed, the environment is frozen and cannot be modified.
5
+ * Provides a read-only interface similar to process.env.
6
+ *
7
+ * @module env
8
+ */
9
+
10
+ /**
11
+ * Immutable environment variable store.
12
+ */
13
+ export class Environment {
14
+ #vars;
15
+
16
+ /**
17
+ * @param {Record<string, string>} [vars={}] - Initial environment variables.
18
+ */
19
+ constructor(vars = {}) {
20
+ this.#vars = Object.freeze({ ...vars });
21
+ }
22
+
23
+ /**
24
+ * Get an environment variable by key.
25
+ *
26
+ * @param {string} key - Variable name.
27
+ * @returns {string|undefined} The value, or undefined if not set.
28
+ */
29
+ get(key) {
30
+ return this.#vars[key];
31
+ }
32
+
33
+ /**
34
+ * Check whether an environment variable exists.
35
+ *
36
+ * @param {string} key - Variable name.
37
+ * @returns {boolean}
38
+ */
39
+ has(key) {
40
+ return key in this.#vars;
41
+ }
42
+
43
+ /**
44
+ * Get a frozen copy of all environment variables.
45
+ *
46
+ * @returns {Readonly<Record<string, string>>}
47
+ */
48
+ all() {
49
+ return this.#vars;
50
+ }
51
+
52
+ /** Number of environment variables. */
53
+ get size() {
54
+ return Object.keys(this.#vars).length;
55
+ }
56
+ }
package/src/errors.mjs ADDED
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Kernel error hierarchy.
3
+ *
4
+ * All kernel errors extend {@link KernelError}, which itself extends the native
5
+ * `Error`. Each subclass carries a POSIX-style `.code` string (e.g. `'ENOHANDLE'`)
6
+ * and additional contextual properties describing the failure.
7
+ *
8
+ * @module errors
9
+ */
10
+
11
+ import { KERNEL_ERROR } from './constants.mjs';
12
+
13
+ /**
14
+ * Base error class for all kernel errors.
15
+ *
16
+ * @property {string} code - Machine-readable error code.
17
+ */
18
+ export class KernelError extends Error {
19
+ /**
20
+ * @param {string} message - Human-readable error description.
21
+ * @param {string} code - Machine-readable error code.
22
+ */
23
+ constructor(message, code) {
24
+ super(message);
25
+ this.name = 'KernelError';
26
+ this.code = code;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Thrown when a resource handle is not found in the ResourceTable.
32
+ *
33
+ * @property {string} handle - The handle that was not found.
34
+ * @property {string} code - Always `'ENOHANDLE'`.
35
+ */
36
+ export class HandleNotFoundError extends KernelError {
37
+ /**
38
+ * @param {string} handle - The handle that was not found.
39
+ */
40
+ constructor(handle) {
41
+ super(`Handle not found: ${handle}`, KERNEL_ERROR.ENOHANDLE);
42
+ this.name = 'HandleNotFoundError';
43
+ this.handle = handle;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Thrown when a resource handle exists but its type does not match the expected type.
49
+ *
50
+ * @property {string} handle - The handle that was accessed.
51
+ * @property {string} expected - The expected resource type.
52
+ * @property {string} actual - The actual resource type.
53
+ * @property {string} code - Always `'EHANDLETYPE'`.
54
+ */
55
+ export class HandleTypeMismatchError extends KernelError {
56
+ /**
57
+ * @param {string} handle - The handle accessed.
58
+ * @param {string} expected - Expected type.
59
+ * @param {string} actual - Actual type.
60
+ */
61
+ constructor(handle, expected, actual) {
62
+ super(`Handle type mismatch: ${handle} expected ${expected}, got ${actual}`, KERNEL_ERROR.EHANDLETYPE);
63
+ this.name = 'HandleTypeMismatchError';
64
+ this.handle = handle;
65
+ this.expected = expected;
66
+ this.actual = actual;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Thrown when the ResourceTable has reached its maximum capacity.
72
+ *
73
+ * @property {number} maxSize - The table's maximum capacity.
74
+ * @property {string} code - Always `'ETABLEFULL'`.
75
+ */
76
+ export class TableFullError extends KernelError {
77
+ /**
78
+ * @param {number} maxSize - Maximum table capacity.
79
+ */
80
+ constructor(maxSize) {
81
+ super(`Resource table full: max ${maxSize} entries`, KERNEL_ERROR.ETABLEFULL);
82
+ this.name = 'TableFullError';
83
+ this.maxSize = maxSize;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Thrown when attempting to read from, write to, or operate on a closed ByteStream.
89
+ *
90
+ * @property {string} code - Always `'ESTREAMCLOSED'`.
91
+ */
92
+ export class StreamClosedError extends KernelError {
93
+ constructor() {
94
+ super('Stream is closed', KERNEL_ERROR.ESTREAMCLOSED);
95
+ this.name = 'StreamClosedError';
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Thrown when a tenant lacks the required capability for an operation.
101
+ *
102
+ * @property {string} capability - The capability that was required but not granted.
103
+ * @property {string} code - Always `'ECAPDENIED'`.
104
+ */
105
+ export class CapabilityDeniedError extends KernelError {
106
+ /**
107
+ * @param {string} capability - The required capability tag.
108
+ */
109
+ constructor(capability) {
110
+ super(`Capability denied: ${capability}`, KERNEL_ERROR.ECAPDENIED);
111
+ this.name = 'CapabilityDeniedError';
112
+ this.capability = capability;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Thrown when attempting to register a name or resource that already exists.
118
+ *
119
+ * @property {string} identifier - The name that was already registered.
120
+ * @property {string} code - Always `'EALREADY'`.
121
+ */
122
+ export class AlreadyRegisteredError extends KernelError {
123
+ /**
124
+ * @param {string} identifier - The duplicate name.
125
+ */
126
+ constructor(identifier) {
127
+ super(`Already registered: ${identifier}`, KERNEL_ERROR.EALREADY);
128
+ this.name = 'AlreadyRegisteredError';
129
+ this.identifier = identifier;
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Thrown when a named resource is not found in a registry or lookup.
135
+ *
136
+ * @property {string} identifier - The name that was not found.
137
+ * @property {string} code - Always `'ENOTFOUND'`.
138
+ */
139
+ export class NotFoundError extends KernelError {
140
+ /**
141
+ * @param {string} identifier - The name that was not found.
142
+ */
143
+ constructor(identifier) {
144
+ super(`Not found: ${identifier}`, KERNEL_ERROR.ENOTFOUND);
145
+ this.name = 'NotFoundError';
146
+ this.identifier = identifier;
147
+ }
148
+ }