diff --git a/app/cli.php b/app/cli.php index 9ad223a3ff..496a79eab9 100644 --- a/app/cli.php +++ b/app/cli.php @@ -2,18 +2,10 @@ require_once __DIR__ . '/init.php'; -use Appwrite\Event\Event; -use Appwrite\Event\Publisher\Certificate as CertificatePublisher; -use Appwrite\Event\Publisher\Database as DatabasePublisher; -use Appwrite\Event\Publisher\Delete as DeletePublisher; -use Appwrite\Event\Publisher\Func as FunctionPublisher; -use Appwrite\Event\Publisher\StatsResources as StatsResourcesPublisher; -use Appwrite\Event\Publisher\Usage as UsagePublisher; use Appwrite\Platform\Appwrite; use Appwrite\Runtimes\Runtimes; use Appwrite\Usage\Context as UsageContext; use Appwrite\Utopia\Database\Documents\User; -use Executor\Executor; use Swoole\Runtime; use Swoole\Timer; use Utopia\Cache\Adapter\Pool as CachePool; @@ -27,17 +19,12 @@ use Utopia\Database\Adapter\Pool as DatabasePool; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; -use Utopia\DI\Container; use Utopia\DSN\DSN; use Utopia\Logger\Log; use Utopia\Platform\Service; use Utopia\Pools\Group; -use Utopia\Queue\Broker\Pool as BrokerPool; -use Utopia\Queue\Publisher; -use Utopia\Queue\Queue; use Utopia\Registry\Registry; use Utopia\System\System; -use Utopia\Telemetry\Adapter\None as NoTelemetry; use function Swoole\Coroutine\run; @@ -48,6 +35,7 @@ Config::setParam('runtimes', (new Runtimes('v5'))->getAll(supported: false)); require_once __DIR__ . '/controllers/general.php'; global $register; +global $container; $platform = new Appwrite(); $args = $_SERVER['argv'] ?? []; @@ -59,7 +47,6 @@ if (! isset($args[0])) { } $taskName = $args[0]; -$container = new Container(); $cli = new CLI(new Generic(), $_SERVER['argv'] ?? [], $container); $platform->setCli($cli); @@ -132,10 +119,6 @@ $container->set('dbForPlatform', function ($pools, $cache, $authorization) { return $dbForPlatform; }, ['pools', 'cache', 'authorization']); -$container->set('console', function () { - return new Document(Config::getParam('console')); -}, []); - $container->set( 'isResourceBlocked', fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false, @@ -252,48 +235,10 @@ $container->set('getLogsDB', function (Group $pools, Cache $cache, Authorization return $database; }; }, ['pools', 'cache', 'authorization']); -$container->set('publisher', function (Group $pools) { - return new BrokerPool(publisher: $pools->get('publisher')); -}, ['pools']); -$container->set('publisherDatabases', function (BrokerPool $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherFunctions', function (BrokerPool $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherMigrations', function (BrokerPool $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherMessaging', function (BrokerPool $publisher) { - return $publisher; -}, ['publisher']); + $container->set('usage', function () { return new UsageContext(); }, []); -$container->set('publisherForUsage', fn (Publisher $publisher) => new UsagePublisher( - $publisher, - new Queue(System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForCertificates', fn (Publisher $publisher) => new CertificatePublisher( - $publisher, - new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForStatsResources', fn (Publisher $publisher) => new StatsResourcesPublisher( - $publisher, - new Queue(System::getEnv('_APP_STATS_RESOURCES_QUEUE_NAME', Event::STATS_RESOURCES_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForFunctions', fn (Publisher $publisher) => new FunctionPublisher( - $publisher, - new Queue(System::getEnv('_APP_FUNCTIONS_QUEUE_NAME', Event::FUNCTIONS_QUEUE_NAME), 'utopia-queue', Event::FUNCTIONS_QUEUE_TTL) -), ['publisher']); -$container->set('publisherForDatabase', fn (Publisher $publisherDatabases) => new DatabasePublisher( - $publisherDatabases, - new Queue(System::getEnv('_APP_DATABASE_QUEUE_NAME', Event::DATABASE_QUEUE_NAME)) -), ['publisherDatabases']); -$container->set('publisherForDeletes', fn (Publisher $publisher) => new DeletePublisher( - $publisher, - new Queue(System::getEnv('_APP_DELETE_QUEUE_NAME', Event::DELETE_QUEUE_NAME)) -), ['publisher']); $container->set('logError', function (Registry $register) { return function (Throwable $error, string $namespace, string $action) use ($register) { Console::error('[Error] Timestamp: ' . date('c', time())); @@ -346,14 +291,10 @@ $container->set('logError', function (Registry $register) { }; }, ['register']); -$container->set('executor', fn () => new Executor(), []); - $container->set('bus', function (Registry $register) use ($container) { return $register->get('bus')->setResolver(fn (string $name) => $container->get($name)); }, ['register']); -$container->set('telemetry', fn () => new NoTelemetry(), []); - $exitCode = 0; $cli diff --git a/app/config/frameworks.php b/app/config/frameworks.php index 6078c53c63..342657017f 100644 --- a/app/config/frameworks.php +++ b/app/config/frameworks.php @@ -14,7 +14,11 @@ return [ 'name' => 'Analog', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/analog/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/analog/env.sh', 'adapters' => [ @@ -40,7 +44,11 @@ return [ 'name' => 'Angular', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/angular/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/angular/env.sh', 'adapters' => [ @@ -66,7 +74,11 @@ return [ 'name' => 'Next.js', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/next-js/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/next-js/env.sh', 'adapters' => [ @@ -91,7 +103,11 @@ return [ 'name' => 'React', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'adapters' => [ 'static' => [ 'key' => 'static', @@ -108,7 +124,11 @@ return [ 'name' => 'Nuxt', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/nuxt/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/nuxt/env.sh', 'adapters' => [ @@ -133,7 +153,11 @@ return [ 'name' => 'Vue.js', 'screenshotSleep' => 5000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'adapters' => [ 'static' => [ 'key' => 'static', @@ -150,7 +174,11 @@ return [ 'name' => 'SvelteKit', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/sveltekit/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/sveltekit/env.sh', 'adapters' => [ @@ -175,7 +203,11 @@ return [ 'name' => 'Astro', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/astro/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/astro/env.sh', 'adapters' => [ @@ -200,7 +232,11 @@ return [ 'name' => 'TanStack Start', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/tanstack-start/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/tanstack-start/env.sh', 'adapters' => [ @@ -225,7 +261,11 @@ return [ 'name' => 'Remix', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'bundleCommand' => 'bash /usr/local/server/helpers/remix/bundle.sh', 'envCommand' => 'source /usr/local/server/helpers/remix/env.sh', 'adapters' => [ @@ -250,7 +290,11 @@ return [ 'name' => 'Lynx', 'screenshotSleep' => 5000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'adapters' => [ 'static' => [ 'key' => 'static', @@ -284,7 +328,11 @@ return [ 'name' => 'React Native', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'adapters' => [ 'static' => [ 'key' => 'static', @@ -301,7 +349,11 @@ return [ 'name' => 'Vite', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'adapters' => [ 'static' => [ 'key' => 'static', @@ -317,7 +369,11 @@ return [ 'name' => 'Other', 'screenshotSleep' => 3000, 'buildRuntime' => 'node-22', - 'runtimes' => $templateRuntimes['NODE'], + 'runtimes' => array_merge( + $templateRuntimes['NODE'], + $templateRuntimes['BUN'], + $templateRuntimes['DENO'] + ), 'adapters' => [ 'static' => [ 'key' => 'static', diff --git a/app/init/resources.php b/app/init/resources.php index d48a60c06c..7b7e13482c 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -53,6 +53,93 @@ global $register; global $container; $container = new Container(); +$container->set('console', fn () => new Document(Config::getParam('console')), []); + +$container->set('executor', fn () => new Executor(), []); + +$container->set('telemetry', fn () => new NoTelemetry(), []); + +$container->set('publisher', fn (Group $pools) => new BrokerPool(publisher: $pools->get('publisher')), ['pools']); + +$container->set('publisherDatabases', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherFunctions', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherMigrations', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherMails', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherDeletes', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherMessaging', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherWebhooks', fn (Publisher $publisher) => $publisher, ['publisher']); + +$container->set('publisherForAudits', fn (Publisher $publisher) => new AuditPublisher( + $publisher, + new Queue(System::getEnv('_APP_AUDITS_QUEUE_NAME', Event::AUDITS_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForCertificates', fn (Publisher $publisher) => new CertificatePublisher( + $publisher, + new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForScreenshots', fn (Publisher $publisher) => new ScreenshotPublisher( + $publisher, + new Queue(System::getEnv('_APP_SCREENSHOTS_QUEUE_NAME', Event::SCREENSHOTS_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForUsage', fn (Publisher $publisher) => new UsagePublisher( + $publisher, + new Queue(System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForExecutions', fn (Publisher $publisher) => new ExecutionPublisher( + $publisher, + new Queue(System::getEnv('_APP_EXECUTIONS_QUEUE_NAME', Event::EXECUTIONS_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForFunctions', fn (Publisher $publisher) => new FunctionPublisher( + $publisher, + new Queue(System::getEnv('_APP_FUNCTIONS_QUEUE_NAME', Event::FUNCTIONS_QUEUE_NAME), 'utopia-queue', Event::FUNCTIONS_QUEUE_TTL) +), ['publisher']); + +$container->set('publisherForMigrations', fn (Publisher $publisher) => new MigrationPublisher( + $publisher, + new Queue(System::getEnv('_APP_MIGRATIONS_QUEUE_NAME', Event::MIGRATIONS_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForStatsResources', fn (Publisher $publisher) => new StatsResourcesPublisher( + $publisher, + new Queue(System::getEnv('_APP_STATS_RESOURCES_QUEUE_NAME', Event::STATS_RESOURCES_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForBuilds', fn (Publisher $publisher) => new BuildPublisher( + $publisher, + new Queue(System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForDatabase', fn (Publisher $publisherDatabases) => new DatabasePublisher( + $publisherDatabases, + new Queue(System::getEnv('_APP_DATABASE_QUEUE_NAME', Event::DATABASE_QUEUE_NAME)) +), ['publisherDatabases']); + +$container->set('publisherForDeletes', fn (Publisher $publisher) => new DeletePublisher( + $publisher, + new Queue(System::getEnv('_APP_DELETE_QUEUE_NAME', Event::DELETE_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForMails', fn (Publisher $publisher) => new MailPublisher( + $publisher, + new Queue(System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME)) +), ['publisher']); + +$container->set('publisherForMessaging', fn (Publisher $publisher) => new MessagingPublisher( + $publisher, + new Queue(System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME)) +), ['publisher']); + $container->set('logger', function ($register) { return $register->get('logger'); }, ['register']); @@ -67,83 +154,6 @@ $container->set('localeCodes', function () { return array_map(fn ($locale) => $locale['code'], Config::getParam('locale-codes', [])); }); -// Queues - shared infrastructure (stateless pool wrappers) -$container->set('publisher', function (Group $pools) { - return new BrokerPool(publisher: $pools->get('publisher')); -}, ['pools']); -$container->set('publisherDatabases', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherFunctions', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherMigrations', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherMails', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherDeletes', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherMessaging', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherWebhooks', function (Publisher $publisher) { - return $publisher; -}, ['publisher']); -$container->set('publisherForAudits', fn (Publisher $publisher) => new AuditPublisher( - $publisher, - new Queue(System::getEnv('_APP_AUDITS_QUEUE_NAME', Event::AUDITS_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForCertificates', fn (Publisher $publisher) => new CertificatePublisher( - $publisher, - new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForScreenshots', fn (Publisher $publisher) => new ScreenshotPublisher( - $publisher, - new Queue(System::getEnv('_APP_SCREENSHOTS_QUEUE_NAME', Event::SCREENSHOTS_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForUsage', fn (Publisher $publisher) => new UsagePublisher( - $publisher, - new Queue(System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForExecutions', fn (Publisher $publisher) => new ExecutionPublisher( - $publisher, - new Queue(System::getEnv('_APP_EXECUTIONS_QUEUE_NAME', Event::EXECUTIONS_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForFunctions', fn (Publisher $publisher) => new FunctionPublisher( - $publisher, - new Queue(System::getEnv('_APP_FUNCTIONS_QUEUE_NAME', Event::FUNCTIONS_QUEUE_NAME), 'utopia-queue', Event::FUNCTIONS_QUEUE_TTL) -), ['publisher']); -$container->set('publisherForMigrations', fn (Publisher $publisher) => new MigrationPublisher( - $publisher, - new Queue(System::getEnv('_APP_MIGRATIONS_QUEUE_NAME', Event::MIGRATIONS_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForStatsResources', fn (Publisher $publisher) => new StatsResourcesPublisher( - $publisher, - new Queue(System::getEnv('_APP_STATS_RESOURCES_QUEUE_NAME', Event::STATS_RESOURCES_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForBuilds', fn (Publisher $publisher) => new BuildPublisher( - $publisher, - new Queue(System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForDatabase', fn (Publisher $publisherDatabases) => new DatabasePublisher( - $publisherDatabases, - new Queue(System::getEnv('_APP_DATABASE_QUEUE_NAME', Event::DATABASE_QUEUE_NAME)) -), ['publisherDatabases']); -$container->set('publisherForDeletes', fn (Publisher $publisher) => new DeletePublisher( - $publisher, - new Queue(System::getEnv('_APP_DELETE_QUEUE_NAME', Event::DELETE_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForMails', fn (Publisher $publisher) => new MailPublisher( - $publisher, - new Queue(System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME)) -), ['publisher']); -$container->set('publisherForMessaging', fn (Publisher $publisher) => new MessagingPublisher( - $publisher, - new Queue(System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME)) -), ['publisher']); /** * Platform configuration @@ -152,10 +162,6 @@ $container->set('platform', function () { return Config::getParam('platform', []); }, []); -$container->set('console', function () { - return new Document(Config::getParam('console')); -}, []); - $container->set('authorization', function () { return new Authorization(); }, []); @@ -214,8 +220,6 @@ $container->set('getLogsDB', function (Group $pools, Cache $cache, Authorization }; }, ['pools', 'cache', 'authorization']); -$container->set('telemetry', fn () => new NoTelemetry()); - $container->set('cache', function (Group $pools, Telemetry $telemetry) { $list = Config::getParam('pools-cache', []); $adapters = []; @@ -416,5 +420,3 @@ $container->set( 'isResourceBlocked', fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false ); - -$container->set('executor', fn () => new Executor()); diff --git a/app/init/worker/message.php b/app/init/worker/message.php index 3585421a28..5cabfc7859 100644 --- a/app/init/worker/message.php +++ b/app/init/worker/message.php @@ -1,7 +1,6 @@ set('publisherForFunctions', fn (Publisher $publisher) => new FunctionPublisher( - $publisher, - new Queue(System::getEnv('_APP_FUNCTIONS_QUEUE_NAME', Event::FUNCTIONS_QUEUE_NAME), 'utopia-queue', Event::FUNCTIONS_QUEUE_TTL) - ), ['publisher']); $container->set('queueForRealtime', function () { return new Realtime(); }, []); diff --git a/docs/sdks/unity/GETTING_STARTED.md b/docs/sdks/unity/GETTING_STARTED.md new file mode 100644 index 0000000000..7e1f37879c --- /dev/null +++ b/docs/sdks/unity/GETTING_STARTED.md @@ -0,0 +1,116 @@ +## Getting Started + +Before you begin, create an Appwrite project and add a Unity platform in your Appwrite Console. + +This SDK requires the following Unity packages and libraries: + +- [**UniTask**](https://github.com/Cysharp/UniTask): For async/await support in Unity. +- [**NativeWebSocket**](https://github.com/endel/NativeWebSocket): For WebSocket realtime subscriptions. +- **System.Text.Json**: For JSON serialization, provided as a DLL in the project. + +After installing the SDK, open **Appwrite → Setup Assistant** in Unity and install the required dependencies. + +### Configure the SDK + +Create an Appwrite configuration using the **QuickStart** window in the **Appwrite Setup Assistant**, or through **Appwrite → Create Configuration**. + +### Using AppwriteManager + +```csharp +[SerializeField] private AppwriteConfig config; +private AppwriteManager _manager; + +private async UniTask ExampleWithManager() +{ + _manager = AppwriteManager.Instance ?? new GameObject("AppwriteManager").AddComponent(); + _manager.SetConfig(config); + + var success = await _manager.Initialize(needRealtime: true); + if (!success) + { + Debug.LogError("Failed to initialize AppwriteManager"); + return; + } + + var client = _manager.Client; + var pingResult = await client.Ping(); + Debug.Log($"Ping result: {pingResult}"); + + var realtime = _manager.Realtime; + var subscription = realtime.Subscribe( + new[] { "databases.*.collections.*.documents" }, + response => + { + var eventName = response.Events != null && response.Events.Length > 0 + ? response.Events[0] + : "unknown"; + + Debug.Log($"Realtime event: {eventName}"); + } + ); + + // Keep a reference to close the subscription when your MonoBehaviour is destroyed. + // subscription.Close(); +} +``` + +### Using Client directly + +```csharp +private async UniTask ExampleWithDirectClient() +{ + var client = Client.From( + projectId: "", + endpoint: "https://.cloud.appwrite.io/v1", + endpointRealtime: "wss://.cloud.appwrite.io/v1"); + + var pingResult = await client.Ping(); + Debug.Log($"Direct client ping: {pingResult}"); +} +``` + +You can also create authenticated clients with `Client.FromSession`, `Client.FromDevKey`, or `Client.FromImpersonation` when those authentication flows are needed. + +### Error handling + +```csharp +try +{ + var result = await client.Ping(); +} +catch (AppwriteException ex) +{ + Debug.LogError($"Appwrite Error: {ex.Message}"); + Debug.LogError($"Status Code: {ex.Code}"); + Debug.LogError($"Response: {ex.Response}"); +} +``` + +## Preparing Models for Databases API + +When working with the Databases API in Unity, models should be prepared for serialization using the System.Text.Json library. System.Text.Json uses CLR property names by default unless a naming policy is configured. If your project or SDK configuration serializes property names differently from your Appwrite collection attributes, this can cause errors due to mismatches between serialized property names and actual attribute names in your collection. + +To avoid this, add the `JsonPropertyName` attribute to each property in your model class to match the attribute name in Appwrite: + +```csharp +using System.Text.Json.Serialization; + +public class TestModel +{ + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("release_date")] + public System.DateTime ReleaseDate { get; set; } +} +``` + +The `JsonPropertyName` attribute ensures your data object is serialized with the correct attribute names for Appwrite databases. + +### Learn more +You can use the following resources to learn more and get help: + +- 🚀 [Getting Started Tutorial](https://appwrite.io/docs/getting-started-for-client) +- 📜 [Appwrite Docs](https://appwrite.io/docs) +- 💬 [Discord Community](https://appwrite.io/discord) +- 🧰 [Appwrite SDK Generator](https://github.com/appwrite/sdk-generator) diff --git a/src/Appwrite/Platform/Modules/Health/Http/Health/Cache/Get.php b/src/Appwrite/Platform/Modules/Health/Http/Health/Cache/Get.php index bf7c3c4889..8d717eb9ab 100644 --- a/src/Appwrite/Platform/Modules/Health/Http/Health/Cache/Get.php +++ b/src/Appwrite/Platform/Modules/Health/Http/Health/Cache/Get.php @@ -8,12 +8,10 @@ use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response; -use Utopia\Cache\Adapter\Pool as CachePool; -use Utopia\Config\Config; +use Utopia\Cache\Cache; use Utopia\Database\Document; use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; -use Utopia\Pools\Group; class Get extends Action { @@ -47,45 +45,32 @@ class Get extends Action contentType: ContentType::JSON )) ->inject('response') - ->inject('pools') + ->inject('cache') ->callback($this->action(...)); } - public function action(Response $response, Group $pools): void + public function action(Response $response, Cache $cache): void { $output = []; - $failures = []; - $configs = [ - 'Cache' => Config::getParam('pools-cache'), - ]; + $checkStart = \microtime(true); - foreach ($configs as $key => $config) { - foreach ($config as $cache) { - try { - $adapter = new CachePool($pools->get($cache)); - - $checkStart = \microtime(true); - - if ($adapter->ping()) { - $output[] = new Document([ - 'name' => $key . " ($cache)", - 'status' => 'pass', - 'ping' => \round((\microtime(true) - $checkStart) * 1000), - ]); - } else { - $failures[] = $cache; - } - } catch (\Throwable) { - $failures[] = $cache; - } - } + try { + $ok = $cache->ping(); + } catch (\Throwable) { + $ok = false; } - if (!empty($failures)) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Cache failure on: ' . \implode(', ', $failures)); + if (!$ok) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Cache failure on: cache'); } + $output[] = new Document([ + 'name' => 'Cache', + 'status' => 'pass', + 'ping' => \round((\microtime(true) - $checkStart) * 1000), + ]); + $response->dynamic(new Document([ 'statuses' => $output, 'total' => \count($output), diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 03ef72a163..8a3cc65e60 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -1027,6 +1027,7 @@ class Deletes extends Action Query::equal('resourceInternalId', [$resourceInternalId]), Query::equal('resourceType', [$resourceType]), Query::orderDesc('$createdAt'), + Query::orderDesc(), Query::offset($executionsRetentionCount), ]);