KRET LANGUAGE ACADEMY · DOKUMENTACJA ZE ŹRÓDEŁ
Generowanie i sprawdzanie kontraktu
Czego się nauczysz
- Prześledź źródła i wyjaśnij opisany kontrakt.
- Porównaj deklarację mostu i wygenerowaną stronę kontraktu w GenerateAndCheck.
Wymagania wstępne
- Ukończ Podstawy i wcześniejszy poziom tej ścieżki.
Wyjaśnienie krok po kroku
GenerateAndCheck jest materiałem generowania i walidacji lokalnej. Pozytywny wynik nie dowodzi bezpiecznej izolacji natywnej biblioteki ani dostępności mostu w Core. Witryna nie uruchamia plików C# z przykładu.
Praca z kodem źródłowym
KretBridge: generacja C# i kontrola wywołań (bez uruchamiania usługi)
Szablon SDK `csharp-bridge`: kontrakt `Bridge/calc.klink`, kod KretS `use Kret.Bridge.demo.calc as calc`. `kret bridge generate` tworzy interfejs C#, a `kret check` sprawdza każde wywołanie `calc.*` względem kontraktu. **Usługa C# nie jest uruchamiana**: KretBridge to PROVISIONAL_VERSIONED, w Core zablokowany (FB-07), a proces usługi nie jest piaskownicą.
// <auto-generated>
// Kod wygenerowany z kontraktu KretLink „demo.calc” 1.0.0 (sha256 0be0fd784c282fec55b20706a7d2cde62777d33561a9e0256411ecdf60078e25).
// Nie edytuj ręcznie: zmień plik .klink i uruchom „kret bridge generate”.
// </auto-generated>
#nullable enable
using System.Runtime.CompilerServices;
using System.Text.Json;
using Kret.Bridge;
using Kret.Common;
using Kret.Link;
namespace Kret.Examples.Bridge;
/// <summary>Usługa demo.calc 1.0.0. Implementacja działa w procesie usługi KretBridge.</summary>
public interface IDemoCalc
{
/// <summary>Suma dwóch liczb całkowitych.</summary>
Task<long> AddAsync(long a, long b, LinkCallContext context, CancellationToken cancellation);
/// <summary>Kończy proces usługi w trakcie wywołania (test awarii).</summary>
Task<long> CrashAsync(LinkCallContext context, CancellationToken cancellation);
/// <summary>Opis złożony z nazwy i posortowanych etykiet.</summary>
Task<string> DescribeAsync(string name, IReadOnlyDictionary<string, string> tags, LinkCallContext context, CancellationToken cancellation);
/// <summary>Średnia; null dla pustej listy.</summary>
Task<double?> MeanAsync(IReadOnlyList<double> values, LinkCallContext context, CancellationToken cancellation);
/// <summary>Kolejne liczby pierwsze mniejsze od limitu.</summary>
IAsyncEnumerable<long> PrimesAsync(long limit, LinkCallContext context, CancellationToken cancellation);
/// <summary>Operacja wymagająca dodatkowego uprawnienia.</summary>
Task PublishAsync(string text, LinkCallContext context, CancellationToken cancellation);
/// <summary>Czeka podaną liczbę milisekund.</summary>
Task<bool> SlowAsync(long ms, LinkCallContext context, CancellationToken cancellation);
}
/// <summary>Kontrakt usługi osadzony w kodzie — ten sam, z którego wygenerowano interfejs.</summary>
public static class DemoCalcContract
{
public const string Service = "demo.calc";
public const string Version = "1.0.0";
public const string Digest = "0be0fd784c282fec55b20706a7d2cde62777d33561a9e0256411ecdf60078e25";
public const string Json = """"{"format":"kretlink-contract/1","service":"demo.calc","version":"1.0.0","methods":[{"name":"add","description":"Suma dw\u00F3ch liczb ca\u0142kowitych.","params":[{"name":"a","type":"Int64"},{"name":"b","type":"Int64"}],"returns":"Int64","stream":false,"permissions":[],"timeoutMs":5000},{"name":"crash","description":"Ko\u0144czy proces us\u0142ugi w trakcie wywo\u0142ania (test awarii).","params":[],"returns":"Int64","stream":false,"permissions":[],"timeoutMs":5000},{"name":"describe","description":"Opis z\u0142o\u017Cony z nazwy i posortowanych etykiet.","params":[{"name":"name","type":"String"},{"name":"tags","type":"Map\u003CString, String\u003E"}],"returns":"String","stream":false,"permissions":[],"timeoutMs":5000},{"name":"mean","description":"\u015Arednia; null dla pustej listy.","params":[{"name":"values","type":"List\u003CFloat64\u003E"}],"returns":"Float64?","stream":false,"permissions":[],"timeoutMs":5000},{"name":"primes","description":"Kolejne liczby pierwsze mniejsze od limitu.","params":[{"name":"limit","type":"Int64"}],"returns":"Int64","stream":true,"permissions":[],"timeoutMs":5000},{"name":"publish","description":"Operacja wymagaj\u0105ca dodatkowego uprawnienia.","params":[{"name":"text","type":"String"}],"returns":"Unit","stream":false,"permissions":["kretlink.publish"],"timeoutMs":5000},{"name":"slow","description":"Czeka podan\u0105 liczb\u0119 milisekund.","params":[{"name":"ms","type":"Int64"}],"returns":"Bool","stream":false,"permissions":[],"timeoutMs":1000}]}"""";
public static LinkContract Load()
{
var diagnostics = new KcsDiagnostics();
return LinkContract.Read(System.Text.Encoding.UTF8.GetBytes(Json), diagnostics) ?? throw new InvalidOperationException("osadzony kontrakt jest niepoprawny: " + string.Join("; ", diagnostics.Items));
}
}
/// <summary>Rejestracja metod usługi: odczyt argumentów, wywołanie implementacji, zapis wyniku.</summary>
public static class DemoCalcService
{
public static LinkServer Register(LinkServer server, IDemoCalc implementation)
{
server.Handle("add", async (context, arguments, cancellation) =>
{
var result = await implementation.AddAsync(arguments[0].GetInt64(), arguments[1].GetInt64(), context, cancellation).ConfigureAwait(false);
return BridgeJson.Text(writer => writer.WriteNumberValue(result));
});
server.Handle("crash", async (context, arguments, cancellation) =>
{
var result = await implementation.CrashAsync(context, cancellation).ConfigureAwait(false);
return BridgeJson.Text(writer => writer.WriteNumberValue(result));
});
server.Handle("describe", async (context, arguments, cancellation) =>
{
var result = await implementation.DescribeAsync(arguments[0].GetString()!, BridgeJson.Map(arguments[1], e0 => e0.GetString()!), context, cancellation).ConfigureAwait(false);
return BridgeJson.Text(writer => writer.WriteStringValue(result));
});
server.Handle("mean", async (context, arguments, cancellation) =>
{
var result = await implementation.MeanAsync(BridgeJson.List(arguments[0], e0 => e0.GetDouble()), context, cancellation).ConfigureAwait(false);
return BridgeJson.Text(writer => BridgeJson.WriteOptionalValue(writer, result, (w0, v0) => w0.WriteNumberValue(v0)));
});
server.HandleStream("primes", (context, arguments, cancellation) => PrimesItems(implementation, context, arguments, cancellation));
server.Handle("publish", async (context, arguments, cancellation) =>
{
await implementation.PublishAsync(arguments[0].GetString()!, context, cancellation).ConfigureAwait(false);
return "null";
});
server.Handle("slow", async (context, arguments, cancellation) =>
{
var result = await implementation.SlowAsync(arguments[0].GetInt64(), context, cancellation).ConfigureAwait(false);
return BridgeJson.Text(writer => writer.WriteBooleanValue(result));
});
return server;
}
private static async IAsyncEnumerable<string> PrimesItems(IDemoCalc implementation, LinkCallContext context, JsonElement arguments, [EnumeratorCancellation] CancellationToken cancellation)
{
await foreach (var item in implementation.PrimesAsync(arguments[0].GetInt64(), context, cancellation).WithCancellation(cancellation).ConfigureAwait(false))
yield return BridgeJson.Text(writer => writer.WriteNumberValue(item));
}
}
/// <summary>Typowany klient usługi demo.calc dla kodu C#.</summary>
public sealed class DemoCalcClient(LinkClient client)
{
public async Task<long> AddAsync(long a, long b, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>
BridgeJson.Parse(await client.CallAsync("add", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteNumberValue(a); writer.WriteNumberValue(b); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetInt64());
public async Task<long> CrashAsync(TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>
BridgeJson.Parse(await client.CallAsync("crash", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetInt64());
public async Task<string> DescribeAsync(string name, IReadOnlyDictionary<string, string> tags, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>
BridgeJson.Parse(await client.CallAsync("describe", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteStringValue(name); BridgeJson.WriteMap(writer, tags, (w0, v0) => w0.WriteStringValue(v0)); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetString()!);
public async Task<double?> MeanAsync(IReadOnlyList<double> values, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>
BridgeJson.Parse(await client.CallAsync("mean", BridgeJson.Text(writer => { writer.WriteStartArray(); BridgeJson.WriteList(writer, values, (w0, v0) => w0.WriteNumberValue(v0)); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => BridgeJson.OptionalValue(e, e0 => e0.GetDouble()));
public async IAsyncEnumerable<long> PrimesAsync(long limit, int window = 16, [EnumeratorCancellation] CancellationToken cancellation = default)
{
await foreach (var item in client.StreamAsync("primes", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteNumberValue(limit); writer.WriteEndArray(); }), window, cancellation: cancellation).ConfigureAwait(false))
yield return BridgeJson.Parse(item, e => e.GetInt64());
}
public async Task PublishAsync(string text, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>
await client.CallAsync("publish", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteStringValue(text); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false);
public async Task<bool> SlowAsync(long ms, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>
BridgeJson.Parse(await client.CallAsync("slow", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteNumberValue(ms); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetBoolean());
}
Czytanie kodu linia po linii
Objaśnienia struktury nie są walidacją semantyczną. Szczegółowy kontrakt opisują referencje i README przykładu.
// <auto-generated>Komentarz autora; nie jest wykonywany.// Kod wygenerowany z kontraktu KretLink „demo.calc” 1.0.0 (sha256 0be0fd784c282fec55b20706a7d2cde62777d33561a9e0256411ecdf60078e25).Komentarz autora; nie jest wykonywany.// Nie edytuj ręcznie: zmień plik .klink i uruchom „kret bridge generate”.Komentarz autora; nie jest wykonywany.// </auto-generated>Komentarz autora; nie jest wykonywany.#nullable enableOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.using System.Runtime.CompilerServices;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.using System.Text.Json;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.using Kret.Bridge;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.using Kret.Common;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.using Kret.Link;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.namespace Kret.Examples.Bridge;Pole tożsamości lub wersji w otaczającym bloku; zachowaj jego kontekst.Pusta linia oddziela fragmenty źródła./// <summary>Usługa demo.calc 1.0.0. Implementacja działa w procesie usługi KretBridge.</summary>Komentarz autora; nie jest wykonywany.public interface IDemoCalcOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Suma dwóch liczb całkowitych.</summary>Komentarz autora; nie jest wykonywany.Task<long> AddAsync(long a, long b, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Kończy proces usługi w trakcie wywołania (test awarii).</summary>Komentarz autora; nie jest wykonywany.Task<long> CrashAsync(LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Opis złożony z nazwy i posortowanych etykiet.</summary>Komentarz autora; nie jest wykonywany.Task<string> DescribeAsync(string name, IReadOnlyDictionary<string, string> tags, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Średnia; null dla pustej listy.</summary>Komentarz autora; nie jest wykonywany.Task<double?> MeanAsync(IReadOnlyList<double> values, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Kolejne liczby pierwsze mniejsze od limitu.</summary>Komentarz autora; nie jest wykonywany.IAsyncEnumerable<long> PrimesAsync(long limit, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Operacja wymagająca dodatkowego uprawnienia.</summary>Komentarz autora; nie jest wykonywany.Task PublishAsync(string text, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej./// <summary>Czeka podaną liczbę milisekund.</summary>Komentarz autora; nie jest wykonywany.Task<bool> SlowAsync(long ms, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.}Zamknięcie struktury otwartej we wcześniejszych liniach.Pusta linia oddziela fragmenty źródła./// <summary>Kontrakt usługi osadzony w kodzie — ten sam, z którego wygenerowano interfejs.</summary>Komentarz autora; nie jest wykonywany.public static class DemoCalcContractOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.public const string Service = "demo.calc";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.public const string Version = "1.0.0";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.public const string Digest = "0be0fd784c282fec55b20706a7d2cde62777d33561a9e0256411ecdf60078e25";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.public const string Json = """"{"format":"kretlink-contract/1","service":"demo.calc","version":"1.0.0","methods":[{"name":"add","description":"Suma dw\u00F3ch liczb ca\u0142kowitych.","params":[{"name":"a","type":"Int64"},{"name":"b","type":"Int64"}],"returns":"Int64","stream":false,"permissions":[],"timeoutMs":5000},{"name":"crash","description":"Ko\u0144czy proces us\u0142ugi w trakcie wywo\u0142ania (test awarii).","params":[],"returns":"Int64","stream":false,"permissions":[],"timeoutMs":5000},{"name":"describe","description":"Opis z\u0142o\u017Cony z nazwy i posortowanych etykiet.","params":[{"name":"name","type":"String"},{"name":"tags","type":"Map\u003CString, String\u003E"}],"returns":"String","stream":false,"permissions":[],"timeoutMs":5000},{"name":"mean","description":"\u015Arednia; null dla pustej listy.","params":[{"name":"values","type":"List\u003CFloat64\u003E"}],"returns":"Float64?","stream":false,"permissions":[],"timeoutMs":5000},{"name":"primes","description":"Kolejne liczby pierwsze mniejsze od limitu.","params":[{"name":"limit","type":"Int64"}],"returns":"Int64","stream":true,"permissions":[],"timeoutMs":5000},{"name":"publish","description":"Operacja wymagaj\u0105ca dodatkowego uprawnienia.","params":[{"name":"text","type":"String"}],"returns":"Unit","stream":false,"permissions":["kretlink.publish"],"timeoutMs":5000},{"name":"slow","description":"Czeka podan\u0105 liczb\u0119 milisekund.","params":[{"name":"ms","type":"Int64"}],"returns":"Bool","stream":false,"permissions":[],"timeoutMs":1000}]}"""";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.public static LinkContract Load()Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.var diagnostics = new KcsDiagnostics();Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.return LinkContract.Read(System.Text.Encoding.UTF8.GetBytes(Json), diagnostics) ?? throw new InvalidOperationException("osadzony kontrakt jest niepoprawny: " + string.Join("; ", diagnostics.Items));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.}Zamknięcie struktury otwartej we wcześniejszych liniach.}Zamknięcie struktury otwartej we wcześniejszych liniach.Pusta linia oddziela fragmenty źródła./// <summary>Rejestracja metod usługi: odczyt argumentów, wywołanie implementacji, zapis wyniku.</summary>Komentarz autora; nie jest wykonywany.public static class DemoCalcServiceOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.public static LinkServer Register(LinkServer server, IDemoCalc implementation)Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.server.Handle("add", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.var result = await implementation.AddAsync(arguments[0].GetInt64(), arguments[1].GetInt64(), context, cancellation).ConfigureAwait(false);Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.return BridgeJson.Text(writer => writer.WriteNumberValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.});Zamknięcie struktury otwartej we wcześniejszych liniach.server.Handle("crash", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.var result = await implementation.CrashAsync(context, cancellation).ConfigureAwait(false);Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.return BridgeJson.Text(writer => writer.WriteNumberValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.});Zamknięcie struktury otwartej we wcześniejszych liniach.server.Handle("describe", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.var result = await implementation.DescribeAsync(arguments[0].GetString()!, BridgeJson.Map(arguments[1], e0 => e0.GetString()!), context, cancellation).ConfigureAwait(false);Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.return BridgeJson.Text(writer => writer.WriteStringValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.});Zamknięcie struktury otwartej we wcześniejszych liniach.server.Handle("mean", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.var result = await implementation.MeanAsync(BridgeJson.List(arguments[0], e0 => e0.GetDouble()), context, cancellation).ConfigureAwait(false);Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.return BridgeJson.Text(writer => BridgeJson.WriteOptionalValue(writer, result, (w0, v0) => w0.WriteNumberValue(v0)));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.});Zamknięcie struktury otwartej we wcześniejszych liniach.server.HandleStream("primes", (context, arguments, cancellation) => PrimesItems(implementation, context, arguments, cancellation));Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.server.Handle("publish", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.await implementation.PublishAsync(arguments[0].GetString()!, context, cancellation).ConfigureAwait(false);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.return "null";Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.});Zamknięcie struktury otwartej we wcześniejszych liniach.server.Handle("slow", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.var result = await implementation.SlowAsync(arguments[0].GetInt64(), context, cancellation).ConfigureAwait(false);Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.return BridgeJson.Text(writer => writer.WriteBooleanValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.});Zamknięcie struktury otwartej we wcześniejszych liniach.return server;Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.}Zamknięcie struktury otwartej we wcześniejszych liniach.Pusta linia oddziela fragmenty źródła.private static async IAsyncEnumerable<string> PrimesItems(IDemoCalc implementation, LinkCallContext context, JsonElement arguments, [EnumeratorCancellation] CancellationToken cancellation)Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.await foreach (var item in implementation.PrimesAsync(arguments[0].GetInt64(), context, cancellation).WithCancellation(cancellation).ConfigureAwait(false))Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.yield return BridgeJson.Text(writer => writer.WriteNumberValue(item));Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.}Zamknięcie struktury otwartej we wcześniejszych liniach.}Zamknięcie struktury otwartej we wcześniejszych liniach.Pusta linia oddziela fragmenty źródła./// <summary>Typowany klient usługi demo.calc dla kodu C#.</summary>Komentarz autora; nie jest wykonywany.public sealed class DemoCalcClient(LinkClient client)Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.public async Task<long> AddAsync(long a, long b, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.BridgeJson.Parse(await client.CallAsync("add", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteNumberValue(a); writer.WriteNumberValue(b); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetInt64());Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.public async Task<long> CrashAsync(TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.BridgeJson.Parse(await client.CallAsync("crash", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetInt64());Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.public async Task<string> DescribeAsync(string name, IReadOnlyDictionary<string, string> tags, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.BridgeJson.Parse(await client.CallAsync("describe", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteStringValue(name); BridgeJson.WriteMap(writer, tags, (w0, v0) => w0.WriteStringValue(v0)); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetString()!);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.public async Task<double?> MeanAsync(IReadOnlyList<double> values, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.BridgeJson.Parse(await client.CallAsync("mean", BridgeJson.Text(writer => { writer.WriteStartArray(); BridgeJson.WriteList(writer, values, (w0, v0) => w0.WriteNumberValue(v0)); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => BridgeJson.OptionalValue(e, e0 => e0.GetDouble()));Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.public async IAsyncEnumerable<long> PrimesAsync(long limit, int window = 16, [EnumeratorCancellation] CancellationToken cancellation = default)Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.{Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.await foreach (var item in client.StreamAsync("primes", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteNumberValue(limit); writer.WriteEndArray(); }), window, cancellation: cancellation).ConfigureAwait(false))Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.yield return BridgeJson.Parse(item, e => e.GetInt64());Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.}Zamknięcie struktury otwartej we wcześniejszych liniach.Pusta linia oddziela fragmenty źródła.public async Task PublishAsync(string text, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.await client.CallAsync("publish", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteStringValue(text); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.Pusta linia oddziela fragmenty źródła.public async Task<bool> SlowAsync(long ms, TimeSpan? timeout = null, string? traceId = null, CancellationToken cancellation = default) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.BridgeJson.Parse(await client.CallAsync("slow", BridgeJson.Text(writer => { writer.WriteStartArray(); writer.WriteNumberValue(ms); writer.WriteEndArray(); }), timeout, traceId, cancellation).ConfigureAwait(false), e => e.GetBoolean());Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.}Zamknięcie struktury otwartej we wcześniejszych liniach.Pusta linia oddziela fragmenty źródła.
Oczekiwany wynik: Kod 0 we wszystkich krokach; plik C# ma tę samą treść co `BridgeHost/Calc.g.cs` szablonu (generator deterministyczny).
Typowy błąd: Uznanie KretBridge za mechanizm izolacji. Usługa C# działa z prawami użytkownika — uruchamiaj tylko zaufane usługi i tylko w trybie deweloperskim SDK (`kret run --bridge`).
Instrukcja, wersje i zapisane wyniki →Materiały źródłowe do tego tematu
Przeczytaj powiązane rozdziały. Kod i kontrakty zachowano z importu; historia źródeł jest dostępna przy każdym rozdziale.
KretBridge — API / CLI
KretBridge — API / CLI
Polski
| API / polecenie | Opis |
|---|---|
kret bridge generate <kontrakt.klink> --namespace X -o Plik.g.cs | interfejs C#, rejestracja, klient (deterministycznie) |
kret run … --bridge usługa=program | tryb deweloperski SDK — NIE wykonywane w tej rundzie (przykład VALIDATION_ONLY) |
KretBridge — specyfikacja (zakres kontraktu 1.0)
KretBridge — specyfikacja (zakres kontraktu 1.0)
Status 1.0: `PROVISIONAL_VERSIONED` — zdefiniowane i przetestowane, za mało dowodów na stabilne 1.0; własna ścieżka rozwoju. Gramatyka/wersja: — (kontrakt klink-1.0). Status języka nie nadaje uprawnień KCS ani prawa do działania w Production.Źródła normatywne (kopie w Sources/, kolejność pierwszeństwa: decyzje właściciela → zamrożony kontrakt → kod SDK → testy):
LANGUAGE_FREEZE_1_0/09_KRETBRIDGE_SPECIFICATION.md- SDK
05_Integration/KretBridge/README.md
Elementy języka
| Element | Stan w KretBridge |
|---|---|
| Pliki | kontrakt Bridge/<nazwa>.klink + projekt usługi C# (BridgeHost/). |
| Składnia | składnia kontraktu = KretLink klink-1.0; wywołanie w KretS = zwykłe wywołanie metody. |
Zakres poza kontraktem / ograniczenia
- Kret Engine / Core (zablokowane, FB-07)
- niezaufany kod C# (brak izolacji)
- metody strumieniowe z KretS (KretS 2.0 ich nie wywołuje)
- KretBridge 1.0 → FROZEN dopiero po izolowanym hoście usług C# i decyzji właściciela.
- Most
KretCore.SDK.CSharp(Core 1.0) — LEGACY. - Linux/macOS: NOT_RUN.
Pełna referencja konstrukcji: SYNTAX_REFERENCE.md.
KretBridge — samouczek INTERMEDIATE
KretBridge — samouczek INTERMEDIATE
Status 1.0: `PROVISIONAL_VERSIONED` — zdefiniowane i przetestowane, za mało dowodów na stabilne 1.0; własna ścieżka rozwoju. Gramatyka/wersja: — (kontrakt klink-1.0). Status języka nie nadaje uprawnień KCS ani prawa do działania w Production.Cel: moduły, łączenie funkcji, dane, konfiguracja, komunikacja, obsługa błędów, interfejsy SDK.
Narzędzia: kret = <SDK>\Compiler\kret.exe (SDK 1.0.0-rc.3+kret.local.3), kretui-host = <SDK>\UiHost\kretui-host.exe. {DATA}/{OUT} = nowe, puste katalogi.
1. KretBridge: generacja C# i kontrola wywołań (bez uruchamiania usługi) (KRETBRIDGE-I01-GenerateAndCheck)
Projekt: ../../Examples/INTERMEDIATE_GenerateAndCheck/ · klasyfikacja VALIDATION_ONLY · Playground LOCAL_VALIDATE
Kroki (katalog roboczy: katalog przykładu):
kret link compile Bridge/calc.klink— w wyniku:KCS-LNK-0121kret bridge generate Bridge/calc.klink -o {OUT}/Calc.g.cskret check . --json— w wyniku:"succeeded": true
Wynik tej rundy: PASS — zob. EXPECTED_OUTPUT.txt.
Ćwiczenie i sprawdzenie wiedzy
Porównaj deklarację mostu i wygenerowaną stronę kontraktu w GenerateAndCheck.
Szkic nie jest wysyłany na serwer i znika po opuszczeniu lekcji. Przed wyjściem możesz go skopiować.Podpowiedzi
- KretBridge łączy KretS z biblioteką C# działającą w **osobnym procesie usługi**, wywoływanej przez brokera jak operacja hosta (KretS → broker → KretLink RPC → proces C# → wynik). Status PROVISIONAL_VERSIONED; **w Core zablokowany** — kod natywny nie jest izolowany jak plugin w AppContainer. To nie jest sandbox dla C#.
- Odczytaj ograniczenia i oczekiwane błędy z dostarczonego samouczka; check i run są oddzielnymi krokami.
Omówienie rozwiązania
Odpowiedź oprzyj na pokazanym kodzie i rozdziale źródłowym. GenerateAndCheck jest materiałem generowania i walidacji lokalnej. Pozytywny wynik nie dowodzi bezpiecznej izolacji natywnej biblioteki ani dostępności mostu w Core. Witryna nie uruchamia plików C# z przykładu.
Podsumowanie i następny krok
GenerateAndCheck jest materiałem generowania i walidacji lokalnej. Pozytywny wynik nie dowodzi bezpiecznej izolacji natywnej biblioteki ani dostępności mostu w Core. Witryna nie uruchamia plików C# z przykładu.
Zaloguj się na konto użytkownika, aby zapisywać postęp i zakładki. Konta obsługi mogą czytać bez zapisu postępu. Logowanie →