Przejdź do treści

KRET LANGUAGE ACADEMY · DOKUMENTACJA ZE ŹRÓDEŁ

Generowanie i sprawdzanie kontraktu

INTERMEDIATE30 minAnaliza / koncepcja
Postęp nauki 0 / 3
Zaloguj się na konto użytkownika, aby zachować postęp.

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.

  1. // <auto-generated>Komentarz autora; nie jest wykonywany.
  2. // Kod wygenerowany z kontraktu KretLink „demo.calc” 1.0.0 (sha256 0be0fd784c282fec55b20706a7d2cde62777d33561a9e0256411ecdf60078e25).Komentarz autora; nie jest wykonywany.
  3. // Nie edytuj ręcznie: zmień plik .klink i uruchom „kret bridge generate”.Komentarz autora; nie jest wykonywany.
  4. // </auto-generated>Komentarz autora; nie jest wykonywany.
  5. #nullable enableOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  6. using System.Runtime.CompilerServices;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  7. using System.Text.Json;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  8. using Kret.Bridge;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  9. using Kret.Common;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  10. using Kret.Link;Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  11. Pusta linia oddziela fragmenty źródła.
  12. namespace Kret.Examples.Bridge;Pole tożsamości lub wersji w otaczającym bloku; zachowaj jego kontekst.
  13. Pusta linia oddziela fragmenty źródła.
  14. /// <summary>Usługa demo.calc 1.0.0. Implementacja działa w procesie usługi KretBridge.</summary>Komentarz autora; nie jest wykonywany.
  15. public interface IDemoCalcOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  16. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  17. /// <summary>Suma dwóch liczb całkowitych.</summary>Komentarz autora; nie jest wykonywany.
  18. 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.
  19. /// <summary>Kończy proces usługi w trakcie wywołania (test awarii).</summary>Komentarz autora; nie jest wykonywany.
  20. Task<long> CrashAsync(LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  21. /// <summary>Opis złożony z nazwy i posortowanych etykiet.</summary>Komentarz autora; nie jest wykonywany.
  22. 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.
  23. /// <summary>Średnia; null dla pustej listy.</summary>Komentarz autora; nie jest wykonywany.
  24. 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.
  25. /// <summary>Kolejne liczby pierwsze mniejsze od limitu.</summary>Komentarz autora; nie jest wykonywany.
  26. IAsyncEnumerable<long> PrimesAsync(long limit, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  27. /// <summary>Operacja wymagająca dodatkowego uprawnienia.</summary>Komentarz autora; nie jest wykonywany.
  28. Task PublishAsync(string text, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  29. /// <summary>Czeka podaną liczbę milisekund.</summary>Komentarz autora; nie jest wykonywany.
  30. Task<bool> SlowAsync(long ms, LinkCallContext context, CancellationToken cancellation);Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  31. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  32. Pusta linia oddziela fragmenty źródła.
  33. /// <summary>Kontrakt usługi osadzony w kodzie — ten sam, z którego wygenerowano interfejs.</summary>Komentarz autora; nie jest wykonywany.
  34. public static class DemoCalcContractOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  35. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  36. public const string Service = "demo.calc";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  37. public const string Version = "1.0.0";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  38. public const string Digest = "0be0fd784c282fec55b20706a7d2cde62777d33561a9e0256411ecdf60078e25";Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  39. 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.
  40. Pusta linia oddziela fragmenty źródła.
  41. public static LinkContract Load()Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  42. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  43. var diagnostics = new KcsDiagnostics();Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.
  44. 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.
  45. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  46. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  47. Pusta linia oddziela fragmenty źródła.
  48. /// <summary>Rejestracja metod usługi: odczyt argumentów, wywołanie implementacji, zapis wyniku.</summary>Komentarz autora; nie jest wykonywany.
  49. public static class DemoCalcServiceOdczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  50. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  51. public static LinkServer Register(LinkServer server, IDemoCalc implementation)Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  52. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  53. server.Handle("add", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  54. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  55. 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.
  56. return BridgeJson.Text(writer => writer.WriteNumberValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  57. });Zamknięcie struktury otwartej we wcześniejszych liniach.
  58. server.Handle("crash", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  59. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  60. var result = await implementation.CrashAsync(context, cancellation).ConfigureAwait(false);Wiązanie wartości; typ i możliwość zmiany zależą od użytej deklaracji.
  61. return BridgeJson.Text(writer => writer.WriteNumberValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  62. });Zamknięcie struktury otwartej we wcześniejszych liniach.
  63. server.Handle("describe", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  64. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  65. 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.
  66. return BridgeJson.Text(writer => writer.WriteStringValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  67. });Zamknięcie struktury otwartej we wcześniejszych liniach.
  68. server.Handle("mean", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  69. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  70. 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.
  71. return BridgeJson.Text(writer => BridgeJson.WriteOptionalValue(writer, result, (w0, v0) => w0.WriteNumberValue(v0)));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  72. });Zamknięcie struktury otwartej we wcześniejszych liniach.
  73. 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.
  74. server.Handle("publish", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  75. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  76. 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.
  77. return "null";Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  78. });Zamknięcie struktury otwartej we wcześniejszych liniach.
  79. server.Handle("slow", async (context, arguments, cancellation) =>Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  80. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  81. 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.
  82. return BridgeJson.Text(writer => writer.WriteBooleanValue(result));Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  83. });Zamknięcie struktury otwartej we wcześniejszych liniach.
  84. return server;Zwrócenie wartości z funkcji; nie jest zapisem do dziennika.
  85. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  86. Pusta linia oddziela fragmenty źródła.
  87. 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.
  88. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  89. 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.
  90. yield return BridgeJson.Text(writer => writer.WriteNumberValue(item));Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  91. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  92. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  93. Pusta linia oddziela fragmenty źródła.
  94. /// <summary>Typowany klient usługi demo.calc dla kodu C#.</summary>Komentarz autora; nie jest wykonywany.
  95. public sealed class DemoCalcClient(LinkClient client)Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  96. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  97. 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.
  98. 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.
  99. Pusta linia oddziela fragmenty źródła.
  100. 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.
  101. 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.
  102. Pusta linia oddziela fragmenty źródła.
  103. 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.
  104. 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.
  105. Pusta linia oddziela fragmenty źródła.
  106. 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.
  107. 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.
  108. Pusta linia oddziela fragmenty źródła.
  109. 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.
  110. {Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  111. 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.
  112. yield return BridgeJson.Parse(item, e => e.GetInt64());Odczytaj tę linię w kontekście otaczającego bloku i objaśnień autora poniżej.
  113. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  114. Pusta linia oddziela fragmenty źródła.
  115. 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.
  116. 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.
  117. Pusta linia oddziela fragmenty źródła.
  118. 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.
  119. 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.
  120. }Zamknięcie struktury otwartej we wcześniejszych liniach.
  121. 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 / polecenieOpis
kret bridge generate <kontrakt.klink> --namespace X -o Plik.g.csinterfejs C#, rejestracja, klient (deterministycznie)
kret run … --bridge usługa=programtryb deweloperski SDK — NIE wykonywane w tej rundzie (przykład VALIDATION_ONLY)
Otwórz cały rozdział ze źródłem →
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

ElementStan w KretBridge
Plikikontrakt Bridge/<nazwa>.klink + projekt usługi C# (BridgeHost/).
Składniaskł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.

Otwórz cały rozdział ze źródłem →
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):

  1. kret link compile Bridge/calc.klink — w wyniku: KCS-LNK-0121
  2. kret bridge generate Bridge/calc.klink -o {OUT}/Calc.g.cs
  3. kret check . --json — w wyniku: "succeeded": true

Wynik tej rundy: PASS — zob. EXPECTED_OUTPUT.txt.

Otwórz cały rozdział ze źródłem →

Ć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.

Które podsumowanie jest zgodne z lekcją?

To quiz o opisanym kontrakcie. Nie kompiluje kodu, nie potwierdza wykonania programu i nie przyznaje nagród.

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 →

Wybierz, co możemy zapamiętać w tej przeglądarce. Możesz zmienić decyzję w każdej chwili.

Polityka prywatności