chore: initialize standalone UPM package
Publish UPM package / publish (push) Failing after 1s

This commit is contained in:
2026-08-26 02:49:58 +08:00
commit 6eebb8e8e4
50 changed files with 3458 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
#nullable enable
using System;
using System.Collections.Generic;
namespace ShrinkContext
{
/// <summary>共享存储中的一条依赖绑定:键解析到 realm 后对应的值与提供者纤程。</summary>
public sealed class ShrinkBinding
{
public ShrinkBinding(object? value, ShrinkFiber? provider, string key,
IShrinkCoeffectAccessPolicy? accessPolicy = null)
{
Value = value;
Provider = provider;
Key = key;
AccessPolicy = accessPolicy;
}
public object? Value { get; }
public ShrinkFiber? Provider { get; }
public string Key { get; }
public IShrinkCoeffectAccessPolicy? AccessPolicy { get; }
}
/// <summary>
/// 带命名空间与主版本的类型化余效应键。现有字符串声明可继续使用 <see cref="Id"/>
/// Set/Get 重载则在调用点固定值类型,逐步收口字符串键的碰撞与接口漂移。
/// </summary>
public sealed class ShrinkKey<T>
{
public ShrinkKey(string packageName, string name, int majorVersion = 1)
{
if (string.IsNullOrWhiteSpace(packageName))
throw new ArgumentException("Package name must not be empty.", nameof(packageName));
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException("Key name must not be empty.", nameof(name));
if (majorVersion <= 0)
throw new ArgumentOutOfRangeException(nameof(majorVersion), "Major version must be positive.");
PackageName = packageName.Trim();
Name = name.Trim();
MajorVersion = majorVersion;
Id = $"{PackageName}/{Name}@v{MajorVersion}";
}
public string PackageName { get; }
public string Name { get; }
public int MajorVersion { get; }
public string Id { get; }
public override string ToString() => Id;
}
/// <summary>依赖值被读取时的访问上下文;metadata 来自访问方上下文上的 intercept 合并结果。</summary>
public sealed class ShrinkCoeffectAccessContext
{
internal ShrinkCoeffectAccessContext(string key, Type requestedType, ShrinkFiber? consumer,
IReadOnlyDictionary<string, object?> metadata)
{
Key = key;
RequestedType = requestedType;
Consumer = consumer;
Metadata = metadata;
}
public string Key { get; }
public Type RequestedType { get; }
public ShrinkFiber? Consumer { get; }
public IReadOnlyDictionary<string, object?> Metadata { get; }
public bool TryGetMetadata<T>(string name, out T value)
{
if (Metadata.TryGetValue(name, out var raw) && raw is T typed)
{
value = typed;
return true;
}
value = default!;
return false;
}
}
/// <summary>
/// provider 侧访问策略。它可以依据 intercept metadata 返回降权包装或拒绝访问,
/// 但不会改变依赖满足关系,也不会构成不可信代码沙箱。
/// </summary>
public interface IShrinkCoeffectAccessPolicy
{
object? Resolve(ShrinkCoeffectAccessContext context, object? value);
}
/// <summary>访问了纤程链上没有任何一方声明的依赖键(论文算法 6 的 UNDECLARED_ACCESS)。</summary>
public sealed class ShrinkUndeclaredAccessException : Exception
{
public ShrinkUndeclaredAccessException(string key)
: base($"Undeclared coeffect access: '{key}'. Declare it in the component's Inject list.")
{
Key = key;
}
public string Key { get; }
}
/// <summary>纤程声明了依赖键但尚未激活就访问(论文算法 6 的 INACTIVE_ACCESS)。</summary>
public sealed class ShrinkInactiveAccessException : Exception
{
public ShrinkInactiveAccessException(string key, string fiberName)
: base($"Inactive coeffect access: '{key}' declared by fiber '{fiberName}' but not committed yet.")
{
Key = key;
}
public string Key { get; }
}
/// <summary>组件写入了未在 Provide 中声明的键。</summary>
public sealed class ShrinkUndeclaredSupplyException : Exception
{
public ShrinkUndeclaredSupplyException(string key, string fiberName)
: base($"Undeclared coeffect supply: '{key}' is not listed in fiber '{fiberName}' Provide keys.")
{
Key = key;
FiberName = fiberName;
}
public string Key { get; }
public string FiberName { get; }
}
/// <summary>intercept 访问策略拒绝了本次依赖读取。</summary>
public sealed class ShrinkCoeffectAccessDeniedException : Exception
{
public ShrinkCoeffectAccessDeniedException(string key, string message)
: base($"Coeffect access denied for '{key}': {message}")
{
Key = key;
}
public string Key { get; }
}
/// <summary>两个活跃纤程试图供给同一个 realm(论文定义 45 的供给不相交约束)。</summary>
public sealed class ShrinkSupplyConflictException : Exception
{
public ShrinkSupplyConflictException(string key, ShrinkFiber? existing, ShrinkFiber? setter)
: base($"Supply conflict on key '{key}': existing provider " +
$"'{existing?.Name ?? "<ambient>"}' conflicts with '{setter?.Name ?? "<ambient>"}'.")
{
Key = key;
}
public string Key { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2dcad9bdadb1607498dc233cfc1b5a06
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: