[{"data":1,"prerenderedAt":2515},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fv1\u002Fexamples\u002Ftask-manager":121,"\u002Fdocs\u002Fv1\u002Fexamples\u002Ftask-manager-surround":2512},[4],{"title":5,"path":6,"stem":7,"children":8,"page":44},"Docs","\u002Fdocs","docs",[9],{"title":10,"path":11,"stem":12,"children":13,"page":44},"V1","\u002Fdocs\u002Fv1","docs\u002Fv1",[14,18,22,45,58,80,93,111],{"title":15,"path":16,"stem":17},"Introduction","\u002Fdocs\u002Fv1\u002Fintroduction","docs\u002Fv1\u002F0.introduction",{"title":19,"path":20,"stem":21},"How It Works","\u002Fdocs\u002Fv1\u002Fhow-it-works","docs\u002Fv1\u002F1.how-it-works",{"title":23,"icon":24,"path":25,"stem":26,"children":27,"page":44},"Client","i-lucide-laptop","\u002Fdocs\u002Fv1\u002Fclient","docs\u002Fv1\u002F2.client",[28,32,36,40],{"title":29,"path":30,"stem":31},"Client Setup","\u002Fdocs\u002Fv1\u002Fclient\u002Fsetup","docs\u002Fv1\u002F2.client\u002F1.setup",{"title":33,"path":34,"stem":35},"Syncing","\u002Fdocs\u002Fv1\u002Fclient\u002Fsyncing","docs\u002Fv1\u002F2.client\u002F2.syncing",{"title":37,"path":38,"stem":39},"Events","\u002Fdocs\u002Fv1\u002Fclient\u002Fevents","docs\u002Fv1\u002F2.client\u002F3.events",{"title":41,"path":42,"stem":43},"Configuration","\u002Fdocs\u002Fv1\u002Fclient\u002Fconfiguration","docs\u002Fv1\u002F2.client\u002F4.configuration",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Server","i-lucide-server","\u002Fdocs\u002Fv1\u002Fserver","docs\u002Fv1\u002F3.server",[51,55],{"title":52,"path":53,"stem":54},"Server Setup","\u002Fdocs\u002Fv1\u002Fserver\u002Fsetup","docs\u002Fv1\u002F3.server\u002F1.setup",{"title":41,"path":56,"stem":57},"\u002Fdocs\u002Fv1\u002Fserver\u002Fconfiguration","docs\u002Fv1\u002F3.server\u002F2.configuration",{"title":59,"icon":60,"badge":61,"path":62,"stem":63,"children":64,"page":44},"NativePHP","i-lucide-smartphone","Commercial","\u002Fdocs\u002Fv1\u002Fnativephp","docs\u002Fv1\u002F4.nativephp",[65,69,73,76],{"title":66,"path":67,"stem":68},"Overview","\u002Fdocs\u002Fv1\u002Fnativephp\u002Foverview","docs\u002Fv1\u002F4.nativephp\u002F1.overview",{"title":70,"path":71,"stem":72},"Setup","\u002Fdocs\u002Fv1\u002Fnativephp\u002Fsetup","docs\u002Fv1\u002F4.nativephp\u002F2.setup",{"title":41,"path":74,"stem":75},"\u002Fdocs\u002Fv1\u002Fnativephp\u002Fconfiguration","docs\u002Fv1\u002F4.nativephp\u002F3.configuration",{"title":77,"path":78,"stem":79},"Lifecycle & Events","\u002Fdocs\u002Fv1\u002Fnativephp\u002Flifecycle","docs\u002Fv1\u002F4.nativephp\u002F4.lifecycle",{"title":81,"icon":82,"badge":61,"path":83,"stem":84,"children":85,"page":44},"Server Pro","i-lucide-bar-chart-2","\u002Fdocs\u002Fv1\u002Fserver-pro","docs\u002Fv1\u002F5.server-pro",[86,89],{"title":66,"path":87,"stem":88},"\u002Fdocs\u002Fv1\u002Fserver-pro\u002Foverview","docs\u002Fv1\u002F5.server-pro\u002F1.overview",{"title":90,"path":91,"stem":92},"Features","\u002Fdocs\u002Fv1\u002Fserver-pro\u002Ffeatures","docs\u002Fv1\u002F5.server-pro\u002F2.features",{"title":94,"icon":95,"path":96,"stem":97,"children":98,"page":44},"Advanced","i-lucide-settings-2","\u002Fdocs\u002Fv1\u002Fadvanced","docs\u002Fv1\u002F6.advanced",[99,103,107],{"title":100,"path":101,"stem":102},"Service Container","\u002Fdocs\u002Fv1\u002Fadvanced\u002Fservice-container","docs\u002Fv1\u002F6.advanced\u002F0.service-container",{"title":104,"path":105,"stem":106},"Conflict Resolution","\u002Fdocs\u002Fv1\u002Fadvanced\u002Fconflict-resolution","docs\u002Fv1\u002F6.advanced\u002F1.conflict-resolution",{"title":108,"path":109,"stem":110},"Payload Mapping","\u002Fdocs\u002Fv1\u002Fadvanced\u002Fpayload-mapping","docs\u002Fv1\u002F6.advanced\u002F2.payload-mapping",{"title":112,"icon":113,"path":114,"stem":115,"children":116,"page":44},"Examples","i-lucide-book-open","\u002Fdocs\u002Fv1\u002Fexamples","docs\u002Fv1\u002F7.examples",[117],{"title":118,"path":119,"stem":120},"Task Manager","\u002Fdocs\u002Fv1\u002Fexamples\u002Ftask-manager","docs\u002Fv1\u002F7.examples\u002F1.task-manager",{"id":122,"title":118,"body":123,"description":2505,"extension":2506,"links":2507,"meta":2508,"navigation":588,"path":119,"seo":2509,"stem":120,"__hash__":2511},"docs\u002Fdocs\u002Fv1\u002F7.examples\u002F1.task-manager.md",{"type":124,"value":125,"toc":2481},"minimark",[126,139,142,147,183,185,189,194,241,245,265,270,535,546,550,553,561,1069,1073,1116,1118,1122,1126,1157,1161,1183,1187,1203,1207,1400,1409,1415,1634,1638,1781,1790,1799,1801,1805,1809,1931,1935,1999,2003,2077,2080,2094,2098,2159,2163,2177,2179,2183,2190,2373,2375,2379,2477],[127,128,129,130,134,135,138],"p",{},"This example builds an offline-first Laravel task manager: a ",[131,132,133],"strong",{},"server"," app that holds the canonical list of tasks, and a ",[131,136,137],{},"client"," app that can create, edit, and delete tasks while offline, then sync and reconcile with the server when appropriate.",[140,141],"hr",{},[143,144,146],"h2",{"id":145},"what-were-building","What we're building",[148,149,150,174,177,180],"ul",{},[151,152,153,154,158,159,162,163,162,166,169,170,173],"li",{},"A ",[155,156,157],"code",{},"Task"," model with ",[155,160,161],{},"title",", ",[155,164,165],{},"description",[155,167,168],{},"status",", and ",[155,171,172],{},"due_date"," fields",[151,175,176],{},"Server exposes the sync endpoint, scoped to tasks owned by the authenticated client",[151,178,179],{},"Client creates and updates tasks locally with no network requirement",[151,181,182],{},"Conflicts fall back to the server's version",[140,184],{},[143,186,188],{"id":187},"part-1-server","Part 1 - Server",[190,191,193],"h3",{"id":192},"_11-install-tetherserver","1.1 Install tether\u002Fserver",[195,196,201],"pre",{"className":197,"code":198,"language":199,"meta":200,"style":200},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","composer require tether\u002Fserver\nphp artisan tether:install-server\nphp artisan migrate\n","bash","",[155,202,203,219,231],{"__ignoreMap":200},[204,205,208,212,216],"span",{"class":206,"line":207},"line",1,[204,209,211],{"class":210},"sBMFI","composer",[204,213,215],{"class":214},"sfazB"," require",[204,217,218],{"class":214}," tether\u002Fserver\n",[204,220,222,225,228],{"class":206,"line":221},2,[204,223,224],{"class":210},"php",[204,226,227],{"class":214}," artisan",[204,229,230],{"class":214}," tether:install-server\n",[204,232,234,236,238],{"class":206,"line":233},3,[204,235,224],{"class":210},[204,237,227],{"class":214},[204,239,240],{"class":214}," migrate\n",[190,242,244],{"id":243},"_12-create-the-task-model-and-migration","1.2 Create the Task model and migration",[195,246,248],{"className":197,"code":247,"language":199,"meta":200,"style":200},"php artisan make:model Task -m\n",[155,249,250],{"__ignoreMap":200},[204,251,252,254,256,259,262],{"class":206,"line":207},[204,253,224],{"class":210},[204,255,227],{"class":214},[204,257,258],{"class":214}," make:model",[204,260,261],{"class":214}," Task",[204,263,264],{"class":214}," -m\n",[127,266,267],{},[131,268,269],{},"Migration:",[195,271,274],{"className":272,"code":273,"language":224,"meta":200,"style":200},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","Schema::create('tasks', function (Blueprint $table) {\n    $table->id();\n    $table->tetherUlid();\n    $table->foreignId('user_id')->constrained()->cascadeOnDelete();\n    $table->string('title');\n    $table->text('description')->nullable();\n    $table->string('status')->default('pending');\n    $table->date('due_date')->nullable();\n    $table->timestamps();\n    $table->softDeletes();\n});\n",[155,275,276,326,342,355,390,413,440,475,501,515,529],{"__ignoreMap":200},[204,277,278,281,285,289,292,295,298,300,303,307,310,313,316,320,323],{"class":206,"line":207},[204,279,280],{"class":210},"Schema",[204,282,284],{"class":283},"sMK4o","::",[204,286,288],{"class":287},"s2Zo4","create",[204,290,291],{"class":283},"(",[204,293,294],{"class":283},"'",[204,296,297],{"class":214},"tasks",[204,299,294],{"class":283},[204,301,302],{"class":283},",",[204,304,306],{"class":305},"spNyl"," function",[204,308,309],{"class":283}," (",[204,311,312],{"class":210},"Blueprint",[204,314,315],{"class":283}," $",[204,317,319],{"class":318},"sTEyZ","table",[204,321,322],{"class":283},")",[204,324,325],{"class":283}," {\n",[204,327,328,331,333,336,339],{"class":206,"line":221},[204,329,330],{"class":283},"    $",[204,332,319],{"class":318},[204,334,335],{"class":283},"->",[204,337,338],{"class":287},"id",[204,340,341],{"class":283},"();\n",[204,343,344,346,348,350,353],{"class":206,"line":233},[204,345,330],{"class":283},[204,347,319],{"class":318},[204,349,335],{"class":283},[204,351,352],{"class":287},"tetherUlid",[204,354,341],{"class":283},[204,356,358,360,362,364,367,369,371,374,376,379,382,385,388],{"class":206,"line":357},4,[204,359,330],{"class":283},[204,361,319],{"class":318},[204,363,335],{"class":283},[204,365,366],{"class":287},"foreignId",[204,368,291],{"class":283},[204,370,294],{"class":283},[204,372,373],{"class":214},"user_id",[204,375,294],{"class":283},[204,377,378],{"class":283},")->",[204,380,381],{"class":287},"constrained",[204,383,384],{"class":283},"()->",[204,386,387],{"class":287},"cascadeOnDelete",[204,389,341],{"class":283},[204,391,393,395,397,399,402,404,406,408,410],{"class":206,"line":392},5,[204,394,330],{"class":283},[204,396,319],{"class":318},[204,398,335],{"class":283},[204,400,401],{"class":287},"string",[204,403,291],{"class":283},[204,405,294],{"class":283},[204,407,161],{"class":214},[204,409,294],{"class":283},[204,411,412],{"class":283},");\n",[204,414,416,418,420,422,425,427,429,431,433,435,438],{"class":206,"line":415},6,[204,417,330],{"class":283},[204,419,319],{"class":318},[204,421,335],{"class":283},[204,423,424],{"class":287},"text",[204,426,291],{"class":283},[204,428,294],{"class":283},[204,430,165],{"class":214},[204,432,294],{"class":283},[204,434,378],{"class":283},[204,436,437],{"class":287},"nullable",[204,439,341],{"class":283},[204,441,443,445,447,449,451,453,455,457,459,461,464,466,468,471,473],{"class":206,"line":442},7,[204,444,330],{"class":283},[204,446,319],{"class":318},[204,448,335],{"class":283},[204,450,401],{"class":287},[204,452,291],{"class":283},[204,454,294],{"class":283},[204,456,168],{"class":214},[204,458,294],{"class":283},[204,460,378],{"class":283},[204,462,463],{"class":287},"default",[204,465,291],{"class":283},[204,467,294],{"class":283},[204,469,470],{"class":214},"pending",[204,472,294],{"class":283},[204,474,412],{"class":283},[204,476,478,480,482,484,487,489,491,493,495,497,499],{"class":206,"line":477},8,[204,479,330],{"class":283},[204,481,319],{"class":318},[204,483,335],{"class":283},[204,485,486],{"class":287},"date",[204,488,291],{"class":283},[204,490,294],{"class":283},[204,492,172],{"class":214},[204,494,294],{"class":283},[204,496,378],{"class":283},[204,498,437],{"class":287},[204,500,341],{"class":283},[204,502,504,506,508,510,513],{"class":206,"line":503},9,[204,505,330],{"class":283},[204,507,319],{"class":318},[204,509,335],{"class":283},[204,511,512],{"class":287},"timestamps",[204,514,341],{"class":283},[204,516,518,520,522,524,527],{"class":206,"line":517},10,[204,519,330],{"class":283},[204,521,319],{"class":318},[204,523,335],{"class":283},[204,525,526],{"class":287},"softDeletes",[204,528,341],{"class":283},[204,530,532],{"class":206,"line":531},11,[204,533,534],{"class":283},"});\n",[127,536,537,538,541,542,545],{},"The ",[155,539,540],{},"timestamps()"," call is required for Syncable server models because Tether uses ",[155,543,544],{},"updated_at"," for pull cursors and conflict checks.",[190,547,549],{"id":548},"_13-apply-syncable-and-define-the-scope","1.3 Apply Syncable and define the scope",[127,551,552],{},"The scope ensures each client only receives its own tasks. The push mutation mapper stamps the authenticated user's ID onto every create, so clients can't write tasks for other users.",[127,554,555],{},[131,556,557,560],{},[155,558,559],{},"app\u002FModels\u002FTask.php",":",[195,562,564],{"className":272,"code":563,"language":224,"meta":200,"style":200},"namespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\Request;\nuse Tether\\Core\\Mutation\\Mutation;\nuse Tether\\Server\\Traits\\Syncable;\n\nclass Task extends Model\n{\n    use SoftDeletes;\n    use Syncable;\n\n    protected $fillable = ['tether_id', 'user_id', 'title', 'description', 'status', 'due_date'];\n\n    public static function tetherScope(Builder $query, string $clientId, Request $request): Builder\n    {\n        return $query->where('user_id', $request->user()->id);\n    }\n\n    public static function tetherPushMutationMapper(\n        Mutation $mutation,\n        Request $request,\n    ): Mutation {\n        return $mutation->withPayload(array_merge($mutation->getPayload(), ['user_id' => $request->user()->id]));\n    }\n}\n",[155,565,566,584,590,615,636,657,675,698,720,724,737,742,753,763,768,836,841,890,896,937,943,948,963,977,989,1000,1058,1063],{"__ignoreMap":200},[204,567,568,572,575,578,581],{"class":206,"line":207},[204,569,571],{"class":570},"sbssI","namespace",[204,573,574],{"class":210}," App",[204,576,577],{"class":283},"\\",[204,579,580],{"class":210},"Models",[204,582,583],{"class":283},";\n",[204,585,586],{"class":206,"line":221},[204,587,589],{"emptyLinePlaceholder":588},true,"\n",[204,591,592,595,598,600,603,605,608,610,613],{"class":206,"line":233},[204,593,594],{"class":570},"use",[204,596,597],{"class":318}," Illuminate",[204,599,577],{"class":283},[204,601,602],{"class":318},"Database",[204,604,577],{"class":283},[204,606,607],{"class":318},"Eloquent",[204,609,577],{"class":283},[204,611,612],{"class":318},"Model",[204,614,583],{"class":283},[204,616,617,619,621,623,625,627,629,631,634],{"class":206,"line":357},[204,618,594],{"class":570},[204,620,597],{"class":318},[204,622,577],{"class":283},[204,624,602],{"class":318},[204,626,577],{"class":283},[204,628,607],{"class":318},[204,630,577],{"class":283},[204,632,633],{"class":318},"SoftDeletes",[204,635,583],{"class":283},[204,637,638,640,642,644,646,648,650,652,655],{"class":206,"line":392},[204,639,594],{"class":570},[204,641,597],{"class":318},[204,643,577],{"class":283},[204,645,602],{"class":318},[204,647,577],{"class":283},[204,649,607],{"class":318},[204,651,577],{"class":283},[204,653,654],{"class":318},"Builder",[204,656,583],{"class":283},[204,658,659,661,663,665,668,670,673],{"class":206,"line":415},[204,660,594],{"class":570},[204,662,597],{"class":318},[204,664,577],{"class":283},[204,666,667],{"class":318},"Http",[204,669,577],{"class":283},[204,671,672],{"class":318},"Request",[204,674,583],{"class":283},[204,676,677,679,682,684,687,689,692,694,696],{"class":206,"line":442},[204,678,594],{"class":570},[204,680,681],{"class":318}," Tether",[204,683,577],{"class":283},[204,685,686],{"class":318},"Core",[204,688,577],{"class":283},[204,690,691],{"class":318},"Mutation",[204,693,577],{"class":283},[204,695,691],{"class":318},[204,697,583],{"class":283},[204,699,700,702,704,706,708,710,713,715,718],{"class":206,"line":477},[204,701,594],{"class":570},[204,703,681],{"class":318},[204,705,577],{"class":283},[204,707,46],{"class":318},[204,709,577],{"class":283},[204,711,712],{"class":318},"Traits",[204,714,577],{"class":283},[204,716,717],{"class":318},"Syncable",[204,719,583],{"class":283},[204,721,722],{"class":206,"line":503},[204,723,589],{"emptyLinePlaceholder":588},[204,725,726,729,731,734],{"class":206,"line":517},[204,727,728],{"class":305},"class",[204,730,261],{"class":210},[204,732,733],{"class":305}," extends",[204,735,736],{"class":210}," Model\n",[204,738,739],{"class":206,"line":531},[204,740,741],{"class":283},"{\n",[204,743,745,748,751],{"class":206,"line":744},12,[204,746,747],{"class":570},"    use",[204,749,750],{"class":318}," SoftDeletes",[204,752,583],{"class":283},[204,754,756,758,761],{"class":206,"line":755},13,[204,757,747],{"class":570},[204,759,760],{"class":318}," Syncable",[204,762,583],{"class":283},[204,764,766],{"class":206,"line":765},14,[204,767,589],{"emptyLinePlaceholder":588},[204,769,771,774,776,779,782,785,787,790,792,794,797,799,801,803,805,807,809,811,813,815,817,819,821,823,825,827,829,831,833],{"class":206,"line":770},15,[204,772,773],{"class":305},"    protected",[204,775,315],{"class":283},[204,777,778],{"class":318},"fillable ",[204,780,781],{"class":283},"=",[204,783,784],{"class":283}," [",[204,786,294],{"class":283},[204,788,789],{"class":214},"tether_id",[204,791,294],{"class":283},[204,793,302],{"class":283},[204,795,796],{"class":283}," '",[204,798,373],{"class":214},[204,800,294],{"class":283},[204,802,302],{"class":283},[204,804,796],{"class":283},[204,806,161],{"class":214},[204,808,294],{"class":283},[204,810,302],{"class":283},[204,812,796],{"class":283},[204,814,165],{"class":214},[204,816,294],{"class":283},[204,818,302],{"class":283},[204,820,796],{"class":283},[204,822,168],{"class":214},[204,824,294],{"class":283},[204,826,302],{"class":283},[204,828,796],{"class":283},[204,830,172],{"class":214},[204,832,294],{"class":283},[204,834,835],{"class":283},"];\n",[204,837,839],{"class":206,"line":838},16,[204,840,589],{"emptyLinePlaceholder":588},[204,842,844,847,850,852,855,857,859,861,864,866,869,871,874,876,879,881,884,887],{"class":206,"line":843},17,[204,845,846],{"class":305},"    public",[204,848,849],{"class":305}," static",[204,851,306],{"class":305},[204,853,854],{"class":287}," tetherScope",[204,856,291],{"class":283},[204,858,654],{"class":210},[204,860,315],{"class":283},[204,862,863],{"class":318},"query",[204,865,302],{"class":283},[204,867,868],{"class":570}," string",[204,870,315],{"class":283},[204,872,873],{"class":318},"clientId",[204,875,302],{"class":283},[204,877,878],{"class":210}," Request",[204,880,315],{"class":283},[204,882,883],{"class":318},"request",[204,885,886],{"class":283},"):",[204,888,889],{"class":210}," Builder\n",[204,891,893],{"class":206,"line":892},18,[204,894,895],{"class":283},"    {\n",[204,897,899,903,905,907,909,912,914,916,918,920,922,924,926,928,931,933,935],{"class":206,"line":898},19,[204,900,902],{"class":901},"s7zQu","        return",[204,904,315],{"class":283},[204,906,863],{"class":318},[204,908,335],{"class":283},[204,910,911],{"class":287},"where",[204,913,291],{"class":283},[204,915,294],{"class":283},[204,917,373],{"class":214},[204,919,294],{"class":283},[204,921,302],{"class":283},[204,923,315],{"class":283},[204,925,883],{"class":318},[204,927,335],{"class":283},[204,929,930],{"class":287},"user",[204,932,384],{"class":283},[204,934,338],{"class":318},[204,936,412],{"class":283},[204,938,940],{"class":206,"line":939},20,[204,941,942],{"class":283},"    }\n",[204,944,946],{"class":206,"line":945},21,[204,947,589],{"emptyLinePlaceholder":588},[204,949,951,953,955,957,960],{"class":206,"line":950},22,[204,952,846],{"class":305},[204,954,849],{"class":305},[204,956,306],{"class":305},[204,958,959],{"class":287}," tetherPushMutationMapper",[204,961,962],{"class":283},"(\n",[204,964,966,969,971,974],{"class":206,"line":965},23,[204,967,968],{"class":210},"        Mutation",[204,970,315],{"class":283},[204,972,973],{"class":318},"mutation",[204,975,976],{"class":283},",\n",[204,978,980,983,985,987],{"class":206,"line":979},24,[204,981,982],{"class":210},"        Request",[204,984,315],{"class":283},[204,986,883],{"class":318},[204,988,976],{"class":283},[204,990,992,995,998],{"class":206,"line":991},25,[204,993,994],{"class":283},"    ):",[204,996,997],{"class":210}," Mutation",[204,999,325],{"class":283},[204,1001,1003,1005,1007,1009,1011,1014,1016,1019,1022,1024,1026,1029,1032,1034,1036,1038,1040,1043,1045,1047,1049,1051,1053,1055],{"class":206,"line":1002},26,[204,1004,902],{"class":901},[204,1006,315],{"class":283},[204,1008,973],{"class":318},[204,1010,335],{"class":283},[204,1012,1013],{"class":287},"withPayload",[204,1015,291],{"class":283},[204,1017,1018],{"class":287},"array_merge",[204,1020,1021],{"class":283},"($",[204,1023,973],{"class":318},[204,1025,335],{"class":283},[204,1027,1028],{"class":287},"getPayload",[204,1030,1031],{"class":283},"(),",[204,1033,784],{"class":283},[204,1035,294],{"class":283},[204,1037,373],{"class":214},[204,1039,294],{"class":283},[204,1041,1042],{"class":283}," =>",[204,1044,315],{"class":283},[204,1046,883],{"class":318},[204,1048,335],{"class":283},[204,1050,930],{"class":287},[204,1052,384],{"class":283},[204,1054,338],{"class":318},[204,1056,1057],{"class":283},"]));\n",[204,1059,1061],{"class":206,"line":1060},27,[204,1062,942],{"class":283},[204,1064,1066],{"class":206,"line":1065},28,[204,1067,1068],{"class":283},"}\n",[190,1070,1072],{"id":1071},"_14-protect-the-sync-endpoints","1.4 Protect the sync endpoints",[195,1074,1076],{"className":272,"code":1075,"language":224,"meta":200,"style":200},"\u002F\u002F config\u002Ftether-server.php\n'middleware' => ['api', 'auth:sanctum'],\n",[155,1077,1078,1084],{"__ignoreMap":200},[204,1079,1080],{"class":206,"line":207},[204,1081,1083],{"class":1082},"sHwdD","\u002F\u002F config\u002Ftether-server.php\n",[204,1085,1086,1088,1091,1093,1095,1097,1099,1102,1104,1106,1108,1111,1113],{"class":206,"line":221},[204,1087,294],{"class":283},[204,1089,1090],{"class":214},"middleware",[204,1092,294],{"class":283},[204,1094,1042],{"class":283},[204,1096,784],{"class":283},[204,1098,294],{"class":283},[204,1100,1101],{"class":214},"api",[204,1103,294],{"class":283},[204,1105,302],{"class":283},[204,1107,796],{"class":283},[204,1109,1110],{"class":214},"auth:sanctum",[204,1112,294],{"class":283},[204,1114,1115],{"class":283},"],\n",[140,1117],{},[143,1119,1121],{"id":1120},"part-2-client","Part 2 - Client",[190,1123,1125],{"id":1124},"_21-install-tetherclient","2.1 Install tether\u002Fclient",[195,1127,1129],{"className":197,"code":1128,"language":199,"meta":200,"style":200},"composer require tether\u002Fclient\nphp artisan tether:install\nphp artisan migrate\n",[155,1130,1131,1140,1149],{"__ignoreMap":200},[204,1132,1133,1135,1137],{"class":206,"line":207},[204,1134,211],{"class":210},[204,1136,215],{"class":214},[204,1138,1139],{"class":214}," tether\u002Fclient\n",[204,1141,1142,1144,1146],{"class":206,"line":221},[204,1143,224],{"class":210},[204,1145,227],{"class":214},[204,1147,1148],{"class":214}," tether:install\n",[204,1150,1151,1153,1155],{"class":206,"line":233},[204,1152,224],{"class":210},[204,1154,227],{"class":214},[204,1156,240],{"class":214},[190,1158,1160],{"id":1159},"_22-configure-the-server-url-and-client-credentials","2.2 Configure the server URL and client credentials",[195,1162,1166],{"className":1163,"code":1164,"language":1165,"meta":200,"style":200},"language-env shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","TETHER_SERVER_PUSH_URL=https:\u002F\u002Fyour-server.example.com\u002Ftether\u002Fpush\nTETHER_SERVER_PULL_URL=https:\u002F\u002Fyour-server.example.com\u002Ftether\u002Fpull\nTETHER_CLIENT_ID=device-abc-123\n","env",[155,1167,1168,1173,1178],{"__ignoreMap":200},[204,1169,1170],{"class":206,"line":207},[204,1171,1172],{},"TETHER_SERVER_PUSH_URL=https:\u002F\u002Fyour-server.example.com\u002Ftether\u002Fpush\n",[204,1174,1175],{"class":206,"line":221},[204,1176,1177],{},"TETHER_SERVER_PULL_URL=https:\u002F\u002Fyour-server.example.com\u002Ftether\u002Fpull\n",[204,1179,1180],{"class":206,"line":233},[204,1181,1182],{},"TETHER_CLIENT_ID=device-abc-123\n",[190,1184,1186],{"id":1185},"_23-create-the-task-model-and-migration","2.3 Create the Task model and migration",[195,1188,1189],{"className":197,"code":247,"language":199,"meta":200,"style":200},[155,1190,1191],{"__ignoreMap":200},[204,1192,1193,1195,1197,1199,1201],{"class":206,"line":207},[204,1194,224],{"class":210},[204,1196,227],{"class":214},[204,1198,258],{"class":214},[204,1200,261],{"class":214},[204,1202,264],{"class":214},[127,1204,1205],{},[131,1206,269],{},[195,1208,1210],{"className":272,"code":1209,"language":224,"meta":200,"style":200},"Schema::create('tasks', function (Blueprint $table) {\n    $table->id();\n    $table->tetherUlid();           \u002F\u002F tether_id char(26) unique nullable\n    $table->string('title');\n    $table->text('description')->nullable();\n    $table->string('status')->default('pending');\n    $table->date('due_date')->nullable();\n    $table->timestamps();\n    $table->softDeletes();\n});\n",[155,1211,1212,1244,1256,1272,1292,1316,1348,1372,1384,1396],{"__ignoreMap":200},[204,1213,1214,1216,1218,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1240,1242],{"class":206,"line":207},[204,1215,280],{"class":210},[204,1217,284],{"class":283},[204,1219,288],{"class":287},[204,1221,291],{"class":283},[204,1223,294],{"class":283},[204,1225,297],{"class":214},[204,1227,294],{"class":283},[204,1229,302],{"class":283},[204,1231,306],{"class":305},[204,1233,309],{"class":283},[204,1235,312],{"class":210},[204,1237,315],{"class":283},[204,1239,319],{"class":318},[204,1241,322],{"class":283},[204,1243,325],{"class":283},[204,1245,1246,1248,1250,1252,1254],{"class":206,"line":221},[204,1247,330],{"class":283},[204,1249,319],{"class":318},[204,1251,335],{"class":283},[204,1253,338],{"class":287},[204,1255,341],{"class":283},[204,1257,1258,1260,1262,1264,1266,1269],{"class":206,"line":233},[204,1259,330],{"class":283},[204,1261,319],{"class":318},[204,1263,335],{"class":283},[204,1265,352],{"class":287},[204,1267,1268],{"class":283},"();",[204,1270,1271],{"class":1082},"           \u002F\u002F tether_id char(26) unique nullable\n",[204,1273,1274,1276,1278,1280,1282,1284,1286,1288,1290],{"class":206,"line":357},[204,1275,330],{"class":283},[204,1277,319],{"class":318},[204,1279,335],{"class":283},[204,1281,401],{"class":287},[204,1283,291],{"class":283},[204,1285,294],{"class":283},[204,1287,161],{"class":214},[204,1289,294],{"class":283},[204,1291,412],{"class":283},[204,1293,1294,1296,1298,1300,1302,1304,1306,1308,1310,1312,1314],{"class":206,"line":392},[204,1295,330],{"class":283},[204,1297,319],{"class":318},[204,1299,335],{"class":283},[204,1301,424],{"class":287},[204,1303,291],{"class":283},[204,1305,294],{"class":283},[204,1307,165],{"class":214},[204,1309,294],{"class":283},[204,1311,378],{"class":283},[204,1313,437],{"class":287},[204,1315,341],{"class":283},[204,1317,1318,1320,1322,1324,1326,1328,1330,1332,1334,1336,1338,1340,1342,1344,1346],{"class":206,"line":415},[204,1319,330],{"class":283},[204,1321,319],{"class":318},[204,1323,335],{"class":283},[204,1325,401],{"class":287},[204,1327,291],{"class":283},[204,1329,294],{"class":283},[204,1331,168],{"class":214},[204,1333,294],{"class":283},[204,1335,378],{"class":283},[204,1337,463],{"class":287},[204,1339,291],{"class":283},[204,1341,294],{"class":283},[204,1343,470],{"class":214},[204,1345,294],{"class":283},[204,1347,412],{"class":283},[204,1349,1350,1352,1354,1356,1358,1360,1362,1364,1366,1368,1370],{"class":206,"line":442},[204,1351,330],{"class":283},[204,1353,319],{"class":318},[204,1355,335],{"class":283},[204,1357,486],{"class":287},[204,1359,291],{"class":283},[204,1361,294],{"class":283},[204,1363,172],{"class":214},[204,1365,294],{"class":283},[204,1367,378],{"class":283},[204,1369,437],{"class":287},[204,1371,341],{"class":283},[204,1373,1374,1376,1378,1380,1382],{"class":206,"line":477},[204,1375,330],{"class":283},[204,1377,319],{"class":318},[204,1379,335],{"class":283},[204,1381,512],{"class":287},[204,1383,341],{"class":283},[204,1385,1386,1388,1390,1392,1394],{"class":206,"line":503},[204,1387,330],{"class":283},[204,1389,319],{"class":318},[204,1391,335],{"class":283},[204,1393,526],{"class":287},[204,1395,341],{"class":283},[204,1397,1398],{"class":206,"line":517},[204,1399,534],{"class":283},[127,1401,1402,1403,1405,1406,1408],{},"The client table also keeps ",[155,1404,540],{}," so local writes maintain standard ",[155,1407,544],{}," values before sync.",[127,1410,1411],{},[131,1412,1413,560],{},[155,1414,559],{},[195,1416,1418],{"className":272,"code":1417,"language":224,"meta":200,"style":200},"namespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Tether\\Client\\Traits\\Syncable;\n\nclass Task extends Model\n{\n    use SoftDeletes;\n    use Syncable;\n\n    protected $fillable = ['title', 'description', 'status', 'due_date'];\n\n    protected array $syncable = ['title', 'description', 'status', 'due_date'];\n}\n",[155,1419,1420,1432,1436,1456,1476,1496,1500,1510,1514,1522,1530,1534,1578,1582,1630],{"__ignoreMap":200},[204,1421,1422,1424,1426,1428,1430],{"class":206,"line":207},[204,1423,571],{"class":570},[204,1425,574],{"class":210},[204,1427,577],{"class":283},[204,1429,580],{"class":210},[204,1431,583],{"class":283},[204,1433,1434],{"class":206,"line":221},[204,1435,589],{"emptyLinePlaceholder":588},[204,1437,1438,1440,1442,1444,1446,1448,1450,1452,1454],{"class":206,"line":233},[204,1439,594],{"class":570},[204,1441,597],{"class":318},[204,1443,577],{"class":283},[204,1445,602],{"class":318},[204,1447,577],{"class":283},[204,1449,607],{"class":318},[204,1451,577],{"class":283},[204,1453,612],{"class":318},[204,1455,583],{"class":283},[204,1457,1458,1460,1462,1464,1466,1468,1470,1472,1474],{"class":206,"line":357},[204,1459,594],{"class":570},[204,1461,597],{"class":318},[204,1463,577],{"class":283},[204,1465,602],{"class":318},[204,1467,577],{"class":283},[204,1469,607],{"class":318},[204,1471,577],{"class":283},[204,1473,633],{"class":318},[204,1475,583],{"class":283},[204,1477,1478,1480,1482,1484,1486,1488,1490,1492,1494],{"class":206,"line":392},[204,1479,594],{"class":570},[204,1481,681],{"class":318},[204,1483,577],{"class":283},[204,1485,23],{"class":318},[204,1487,577],{"class":283},[204,1489,712],{"class":318},[204,1491,577],{"class":283},[204,1493,717],{"class":318},[204,1495,583],{"class":283},[204,1497,1498],{"class":206,"line":415},[204,1499,589],{"emptyLinePlaceholder":588},[204,1501,1502,1504,1506,1508],{"class":206,"line":442},[204,1503,728],{"class":305},[204,1505,261],{"class":210},[204,1507,733],{"class":305},[204,1509,736],{"class":210},[204,1511,1512],{"class":206,"line":477},[204,1513,741],{"class":283},[204,1515,1516,1518,1520],{"class":206,"line":503},[204,1517,747],{"class":570},[204,1519,750],{"class":318},[204,1521,583],{"class":283},[204,1523,1524,1526,1528],{"class":206,"line":517},[204,1525,747],{"class":570},[204,1527,760],{"class":318},[204,1529,583],{"class":283},[204,1531,1532],{"class":206,"line":531},[204,1533,589],{"emptyLinePlaceholder":588},[204,1535,1536,1538,1540,1542,1544,1546,1548,1550,1552,1554,1556,1558,1560,1562,1564,1566,1568,1570,1572,1574,1576],{"class":206,"line":744},[204,1537,773],{"class":305},[204,1539,315],{"class":283},[204,1541,778],{"class":318},[204,1543,781],{"class":283},[204,1545,784],{"class":283},[204,1547,294],{"class":283},[204,1549,161],{"class":214},[204,1551,294],{"class":283},[204,1553,302],{"class":283},[204,1555,796],{"class":283},[204,1557,165],{"class":214},[204,1559,294],{"class":283},[204,1561,302],{"class":283},[204,1563,796],{"class":283},[204,1565,168],{"class":214},[204,1567,294],{"class":283},[204,1569,302],{"class":283},[204,1571,796],{"class":283},[204,1573,172],{"class":214},[204,1575,294],{"class":283},[204,1577,835],{"class":283},[204,1579,1580],{"class":206,"line":755},[204,1581,589],{"emptyLinePlaceholder":588},[204,1583,1584,1586,1589,1591,1594,1596,1598,1600,1602,1604,1606,1608,1610,1612,1614,1616,1618,1620,1622,1624,1626,1628],{"class":206,"line":765},[204,1585,773],{"class":305},[204,1587,1588],{"class":570}," array",[204,1590,315],{"class":283},[204,1592,1593],{"class":318},"syncable ",[204,1595,781],{"class":283},[204,1597,784],{"class":283},[204,1599,294],{"class":283},[204,1601,161],{"class":214},[204,1603,294],{"class":283},[204,1605,302],{"class":283},[204,1607,796],{"class":283},[204,1609,165],{"class":214},[204,1611,294],{"class":283},[204,1613,302],{"class":283},[204,1615,796],{"class":283},[204,1617,168],{"class":214},[204,1619,294],{"class":283},[204,1621,302],{"class":283},[204,1623,796],{"class":283},[204,1625,172],{"class":214},[204,1627,294],{"class":283},[204,1629,835],{"class":283},[204,1631,1632],{"class":206,"line":770},[204,1633,1068],{"class":283},[190,1635,1637],{"id":1636},"_24-configure-the-http-client-to-send-an-auth-token","2.4 Configure the HTTP client to send an auth token",[195,1639,1641],{"className":272,"code":1640,"language":224,"meta":200,"style":200},"\u002F\u002F AppServiceProvider::boot()\nuse GuzzleHttp\\Middleware;\nuse Tether\\Client\\SyncHttpClient;\n\napp(SyncHttpClient::class)->withMiddleware(\n    Middleware::mapRequest(\n        fn ($request) => $request->withHeader('Authorization', 'Bearer '.config('services.tether.token'))\n    )\n);\n",[155,1642,1643,1648,1662,1679,1683,1703,1715,1772,1777],{"__ignoreMap":200},[204,1644,1645],{"class":206,"line":207},[204,1646,1647],{"class":1082},"\u002F\u002F AppServiceProvider::boot()\n",[204,1649,1650,1652,1655,1657,1660],{"class":206,"line":221},[204,1651,594],{"class":570},[204,1653,1654],{"class":318}," GuzzleHttp",[204,1656,577],{"class":283},[204,1658,1659],{"class":318},"Middleware",[204,1661,583],{"class":283},[204,1663,1664,1666,1668,1670,1672,1674,1677],{"class":206,"line":233},[204,1665,594],{"class":570},[204,1667,681],{"class":318},[204,1669,577],{"class":283},[204,1671,23],{"class":318},[204,1673,577],{"class":283},[204,1675,1676],{"class":318},"SyncHttpClient",[204,1678,583],{"class":283},[204,1680,1681],{"class":206,"line":357},[204,1682,589],{"emptyLinePlaceholder":588},[204,1684,1685,1688,1690,1692,1694,1696,1698,1701],{"class":206,"line":392},[204,1686,1687],{"class":287},"app",[204,1689,291],{"class":283},[204,1691,1676],{"class":210},[204,1693,284],{"class":283},[204,1695,728],{"class":570},[204,1697,378],{"class":283},[204,1699,1700],{"class":287},"withMiddleware",[204,1702,962],{"class":283},[204,1704,1705,1708,1710,1713],{"class":206,"line":415},[204,1706,1707],{"class":210},"    Middleware",[204,1709,284],{"class":283},[204,1711,1712],{"class":287},"mapRequest",[204,1714,962],{"class":283},[204,1716,1717,1720,1723,1725,1727,1729,1731,1733,1735,1738,1740,1742,1745,1747,1749,1751,1754,1757,1760,1762,1764,1767,1769],{"class":206,"line":442},[204,1718,1719],{"class":305},"        fn",[204,1721,1722],{"class":283}," ($",[204,1724,883],{"class":318},[204,1726,322],{"class":283},[204,1728,1042],{"class":283},[204,1730,315],{"class":283},[204,1732,883],{"class":318},[204,1734,335],{"class":283},[204,1736,1737],{"class":287},"withHeader",[204,1739,291],{"class":283},[204,1741,294],{"class":283},[204,1743,1744],{"class":214},"Authorization",[204,1746,294],{"class":283},[204,1748,302],{"class":283},[204,1750,796],{"class":283},[204,1752,1753],{"class":214},"Bearer ",[204,1755,1756],{"class":283},"'.",[204,1758,1759],{"class":287},"config",[204,1761,291],{"class":283},[204,1763,294],{"class":283},[204,1765,1766],{"class":214},"services.tether.token",[204,1768,294],{"class":283},[204,1770,1771],{"class":283},"))\n",[204,1773,1774],{"class":206,"line":477},[204,1775,1776],{"class":283},"    )\n",[204,1778,1779],{"class":206,"line":503},[204,1780,412],{"class":283},[127,1782,1783,1785,1786,1789],{},[155,1784,1676],{}," can also be used for request signing, tenant headers, or transport-level logging. See the ",[1787,1788,100],"a",{"href":101}," page for the full container service overview.",[195,1791,1793],{"className":1163,"code":1792,"language":1165,"meta":200,"style":200},"TETHER_SERVER_TOKEN=your-sanctum-token\n",[155,1794,1795],{"__ignoreMap":200},[204,1796,1797],{"class":206,"line":207},[204,1798,1792],{},[140,1800],{},[143,1802,1804],{"id":1803},"part-3-using-it","Part 3 - Using it",[190,1806,1808],{"id":1807},"creating-tasks-works-offline","Creating tasks (works offline)",[195,1810,1812],{"className":272,"code":1811,"language":224,"meta":200,"style":200},"use App\\Models\\Task;\n\n$task = Task::create([\n    'title'   => 'Write tests',\n    'status'  => 'pending',\n    'due_date' => '2026-06-01',\n]);\n\n\u002F\u002F $task->tether_id is now set - no network required\n\u002F\u002F A 'pending' mutation log entry is recorded automatically\n",[155,1813,1814,1830,1834,1853,1874,1893,1912,1917,1921,1926],{"__ignoreMap":200},[204,1815,1816,1818,1820,1822,1824,1826,1828],{"class":206,"line":207},[204,1817,594],{"class":570},[204,1819,574],{"class":318},[204,1821,577],{"class":283},[204,1823,580],{"class":318},[204,1825,577],{"class":283},[204,1827,157],{"class":318},[204,1829,583],{"class":283},[204,1831,1832],{"class":206,"line":221},[204,1833,589],{"emptyLinePlaceholder":588},[204,1835,1836,1839,1842,1844,1846,1848,1850],{"class":206,"line":233},[204,1837,1838],{"class":283},"$",[204,1840,1841],{"class":318},"task ",[204,1843,781],{"class":283},[204,1845,261],{"class":210},[204,1847,284],{"class":283},[204,1849,288],{"class":287},[204,1851,1852],{"class":283},"([\n",[204,1854,1855,1858,1860,1862,1865,1867,1870,1872],{"class":206,"line":357},[204,1856,1857],{"class":283},"    '",[204,1859,161],{"class":214},[204,1861,294],{"class":283},[204,1863,1864],{"class":283},"   =>",[204,1866,796],{"class":283},[204,1868,1869],{"class":214},"Write tests",[204,1871,294],{"class":283},[204,1873,976],{"class":283},[204,1875,1876,1878,1880,1882,1885,1887,1889,1891],{"class":206,"line":392},[204,1877,1857],{"class":283},[204,1879,168],{"class":214},[204,1881,294],{"class":283},[204,1883,1884],{"class":283},"  =>",[204,1886,796],{"class":283},[204,1888,470],{"class":214},[204,1890,294],{"class":283},[204,1892,976],{"class":283},[204,1894,1895,1897,1899,1901,1903,1905,1908,1910],{"class":206,"line":415},[204,1896,1857],{"class":283},[204,1898,172],{"class":214},[204,1900,294],{"class":283},[204,1902,1042],{"class":283},[204,1904,796],{"class":283},[204,1906,1907],{"class":214},"2026-06-01",[204,1909,294],{"class":283},[204,1911,976],{"class":283},[204,1913,1914],{"class":206,"line":442},[204,1915,1916],{"class":283},"]);\n",[204,1918,1919],{"class":206,"line":477},[204,1920,589],{"emptyLinePlaceholder":588},[204,1922,1923],{"class":206,"line":503},[204,1924,1925],{"class":1082},"\u002F\u002F $task->tether_id is now set - no network required\n",[204,1927,1928],{"class":206,"line":517},[204,1929,1930],{"class":1082},"\u002F\u002F A 'pending' mutation log entry is recorded automatically\n",[190,1932,1934],{"id":1933},"updating-and-deleting","Updating and deleting",[195,1936,1938],{"className":272,"code":1937,"language":224,"meta":200,"style":200},"$task->update(['status' => 'in_progress']);\n\u002F\u002F New mutation log entry: operation = 'update'\n\n$task->delete();\n\u002F\u002F Mutation log entry: operation = 'delete'\n",[155,1939,1940,1972,1977,1981,1994],{"__ignoreMap":200},[204,1941,1942,1944,1947,1949,1952,1955,1957,1959,1961,1963,1965,1968,1970],{"class":206,"line":207},[204,1943,1838],{"class":283},[204,1945,1946],{"class":318},"task",[204,1948,335],{"class":283},[204,1950,1951],{"class":287},"update",[204,1953,1954],{"class":283},"([",[204,1956,294],{"class":283},[204,1958,168],{"class":214},[204,1960,294],{"class":283},[204,1962,1042],{"class":283},[204,1964,796],{"class":283},[204,1966,1967],{"class":214},"in_progress",[204,1969,294],{"class":283},[204,1971,1916],{"class":283},[204,1973,1974],{"class":206,"line":221},[204,1975,1976],{"class":1082},"\u002F\u002F New mutation log entry: operation = 'update'\n",[204,1978,1979],{"class":206,"line":233},[204,1980,589],{"emptyLinePlaceholder":588},[204,1982,1983,1985,1987,1989,1992],{"class":206,"line":357},[204,1984,1838],{"class":283},[204,1986,1946],{"class":318},[204,1988,335],{"class":283},[204,1990,1991],{"class":287},"delete",[204,1993,341],{"class":283},[204,1995,1996],{"class":206,"line":392},[204,1997,1998],{"class":1082},"\u002F\u002F Mutation log entry: operation = 'delete'\n",[190,2000,2002],{"id":2001},"sync-it-manually","Sync it manually",[195,2004,2006],{"className":272,"code":2005,"language":224,"meta":200,"style":200},"use Tether\\Client\\Facades\\TetherClient;\n\n$result = TetherClient::sync();\n\n\u002F\u002F $result->pushed    - mutations sent\n\u002F\u002F $result->pulled    - records applied locally\n\u002F\u002F $result->conflicts - conflicts encountered\n\u002F\u002F $result->failed    - rejected mutations\n",[155,2007,2008,2030,2034,2053,2057,2062,2067,2072],{"__ignoreMap":200},[204,2009,2010,2012,2014,2016,2018,2020,2023,2025,2028],{"class":206,"line":207},[204,2011,594],{"class":570},[204,2013,681],{"class":318},[204,2015,577],{"class":283},[204,2017,23],{"class":318},[204,2019,577],{"class":283},[204,2021,2022],{"class":318},"Facades",[204,2024,577],{"class":283},[204,2026,2027],{"class":318},"TetherClient",[204,2029,583],{"class":283},[204,2031,2032],{"class":206,"line":221},[204,2033,589],{"emptyLinePlaceholder":588},[204,2035,2036,2038,2041,2043,2046,2048,2051],{"class":206,"line":233},[204,2037,1838],{"class":283},[204,2039,2040],{"class":318},"result ",[204,2042,781],{"class":283},[204,2044,2045],{"class":210}," TetherClient",[204,2047,284],{"class":283},[204,2049,2050],{"class":287},"sync",[204,2052,341],{"class":283},[204,2054,2055],{"class":206,"line":357},[204,2056,589],{"emptyLinePlaceholder":588},[204,2058,2059],{"class":206,"line":392},[204,2060,2061],{"class":1082},"\u002F\u002F $result->pushed    - mutations sent\n",[204,2063,2064],{"class":206,"line":415},[204,2065,2066],{"class":1082},"\u002F\u002F $result->pulled    - records applied locally\n",[204,2068,2069],{"class":206,"line":442},[204,2070,2071],{"class":1082},"\u002F\u002F $result->conflicts - conflicts encountered\n",[204,2073,2074],{"class":206,"line":477},[204,2075,2076],{"class":1082},"\u002F\u002F $result->failed    - rejected mutations\n",[127,2078,2079],{},"or manually via artisan command:",[195,2081,2083],{"className":197,"code":2082,"language":199,"meta":200,"style":200},"php artisan tether:sync\n",[155,2084,2085],{"__ignoreMap":200},[204,2086,2087,2089,2091],{"class":206,"line":207},[204,2088,224],{"class":210},[204,2090,227],{"class":214},[204,2092,2093],{"class":214}," tether:sync\n",[190,2095,2097],{"id":2096},"scheduling-automatic-sync","Scheduling automatic sync",[195,2099,2101],{"className":272,"code":2100,"language":224,"meta":200,"style":200},"\u002F\u002F routes\u002Fconsole.php\nuse Illuminate\\Support\\Facades\\Schedule;\n\nSchedule::command('tether:sync')->everyFiveMinutes();\n",[155,2102,2103,2108,2130,2134],{"__ignoreMap":200},[204,2104,2105],{"class":206,"line":207},[204,2106,2107],{"class":1082},"\u002F\u002F routes\u002Fconsole.php\n",[204,2109,2110,2112,2114,2116,2119,2121,2123,2125,2128],{"class":206,"line":221},[204,2111,594],{"class":570},[204,2113,597],{"class":318},[204,2115,577],{"class":283},[204,2117,2118],{"class":318},"Support",[204,2120,577],{"class":283},[204,2122,2022],{"class":318},[204,2124,577],{"class":283},[204,2126,2127],{"class":318},"Schedule",[204,2129,583],{"class":283},[204,2131,2132],{"class":206,"line":233},[204,2133,589],{"emptyLinePlaceholder":588},[204,2135,2136,2138,2140,2143,2145,2147,2150,2152,2154,2157],{"class":206,"line":357},[204,2137,2127],{"class":210},[204,2139,284],{"class":283},[204,2141,2142],{"class":287},"command",[204,2144,291],{"class":283},[204,2146,294],{"class":283},[204,2148,2149],{"class":214},"tether:sync",[204,2151,294],{"class":283},[204,2153,378],{"class":283},[204,2155,2156],{"class":287},"everyFiveMinutes",[204,2158,341],{"class":283},[190,2160,2162],{"id":2161},"checking-sync-status","Checking sync status",[195,2164,2166],{"className":197,"code":2165,"language":199,"meta":200,"style":200},"php artisan tether:status\n",[155,2167,2168],{"__ignoreMap":200},[204,2169,2170,2172,2174],{"class":206,"line":207},[204,2171,224],{"class":210},[204,2173,227],{"class":214},[204,2175,2176],{"class":214}," tether:status\n",[140,2178],{},[143,2180,2182],{"id":2181},"part-4-handling-conflicts","Part 4 - Handling conflicts",[127,2184,2185,2186,2189],{},"Listen for the ",[155,2187,2188],{},"TetherConflictDetected"," event to notify users when their change was overridden:",[195,2191,2193],{"className":272,"code":2192,"language":224,"meta":200,"style":200},"use Tether\\Client\\Events\\TetherConflictDetected;\nuse Illuminate\\Support\\Facades\\Log;\n\nEvent::listen(TetherConflictDetected::class, function (TetherConflictDetected $event) {\n    Log::warning('Tether conflict', [\n        'model'  => $event->model,\n        'id'     => $event->entityId,\n        'server' => $event->serverState,\n    ]);\n});\n",[155,2194,2195,2215,2236,2240,2275,2299,2321,2343,2364,2369],{"__ignoreMap":200},[204,2196,2197,2199,2201,2203,2205,2207,2209,2211,2213],{"class":206,"line":207},[204,2198,594],{"class":570},[204,2200,681],{"class":318},[204,2202,577],{"class":283},[204,2204,23],{"class":318},[204,2206,577],{"class":283},[204,2208,37],{"class":318},[204,2210,577],{"class":283},[204,2212,2188],{"class":318},[204,2214,583],{"class":283},[204,2216,2217,2219,2221,2223,2225,2227,2229,2231,2234],{"class":206,"line":221},[204,2218,594],{"class":570},[204,2220,597],{"class":318},[204,2222,577],{"class":283},[204,2224,2118],{"class":318},[204,2226,577],{"class":283},[204,2228,2022],{"class":318},[204,2230,577],{"class":283},[204,2232,2233],{"class":318},"Log",[204,2235,583],{"class":283},[204,2237,2238],{"class":206,"line":233},[204,2239,589],{"emptyLinePlaceholder":588},[204,2241,2242,2245,2247,2250,2252,2254,2256,2258,2260,2262,2264,2266,2268,2271,2273],{"class":206,"line":357},[204,2243,2244],{"class":210},"Event",[204,2246,284],{"class":283},[204,2248,2249],{"class":287},"listen",[204,2251,291],{"class":283},[204,2253,2188],{"class":210},[204,2255,284],{"class":283},[204,2257,728],{"class":570},[204,2259,302],{"class":283},[204,2261,306],{"class":305},[204,2263,309],{"class":283},[204,2265,2188],{"class":210},[204,2267,315],{"class":283},[204,2269,2270],{"class":318},"event",[204,2272,322],{"class":283},[204,2274,325],{"class":283},[204,2276,2277,2280,2282,2285,2287,2289,2292,2294,2296],{"class":206,"line":392},[204,2278,2279],{"class":210},"    Log",[204,2281,284],{"class":283},[204,2283,2284],{"class":287},"warning",[204,2286,291],{"class":283},[204,2288,294],{"class":283},[204,2290,2291],{"class":214},"Tether conflict",[204,2293,294],{"class":283},[204,2295,302],{"class":283},[204,2297,2298],{"class":283}," [\n",[204,2300,2301,2304,2307,2309,2311,2313,2315,2317,2319],{"class":206,"line":415},[204,2302,2303],{"class":283},"        '",[204,2305,2306],{"class":214},"model",[204,2308,294],{"class":283},[204,2310,1884],{"class":283},[204,2312,315],{"class":283},[204,2314,2270],{"class":318},[204,2316,335],{"class":283},[204,2318,2306],{"class":318},[204,2320,976],{"class":283},[204,2322,2323,2325,2327,2329,2332,2334,2336,2338,2341],{"class":206,"line":442},[204,2324,2303],{"class":283},[204,2326,338],{"class":214},[204,2328,294],{"class":283},[204,2330,2331],{"class":283},"     =>",[204,2333,315],{"class":283},[204,2335,2270],{"class":318},[204,2337,335],{"class":283},[204,2339,2340],{"class":318},"entityId",[204,2342,976],{"class":283},[204,2344,2345,2347,2349,2351,2353,2355,2357,2359,2362],{"class":206,"line":477},[204,2346,2303],{"class":283},[204,2348,133],{"class":214},[204,2350,294],{"class":283},[204,2352,1042],{"class":283},[204,2354,315],{"class":283},[204,2356,2270],{"class":318},[204,2358,335],{"class":283},[204,2360,2361],{"class":318},"serverState",[204,2363,976],{"class":283},[204,2365,2366],{"class":206,"line":503},[204,2367,2368],{"class":283},"    ]);\n",[204,2370,2371],{"class":206,"line":517},[204,2372,534],{"class":283},[140,2374],{},[143,2376,2378],{"id":2377},"summary","Summary",[319,2380,2381,2395],{},[2382,2383,2384],"thead",{},[2385,2386,2387,2391,2393],"tr",{},[2388,2389,2390],"th",{},"Step",[2388,2392,46],{},[2388,2394,23],{},[2396,2397,2398,2414,2429,2446,2461],"tbody",{},[2385,2399,2400,2404,2409],{},[2401,2402,2403],"td",{},"Install",[2401,2405,2406],{},[155,2407,2408],{},"composer require tether\u002Fserver",[2401,2410,2411],{},[155,2412,2413],{},"composer require tether\u002Fclient",[2385,2415,2416,2419,2424],{},[2401,2417,2418],{},"Migrate",[2401,2420,2421],{},[155,2422,2423],{},"php artisan tether:install-server && migrate",[2401,2425,2426],{},[155,2427,2428],{},"php artisan tether:install && migrate",[2385,2430,2431,2433,2438],{},[2401,2432,612],{},[2401,2434,2435,2437],{},[155,2436,717],{}," + scope + push mutation mapper",[2401,2439,2440,2442,2443,173],{},[155,2441,717],{}," + ",[155,2444,2445],{},"$syncable",[2385,2447,2448,2451,2456],{},[2401,2449,2450],{},"Auth",[2401,2452,2453],{},[155,2454,2455],{},"'middleware' => ['api', 'auth:sanctum']",[2401,2457,2458,2459],{},"Token sent via ",[155,2460,1676],{},[2385,2462,2463,2466,2469],{},[2401,2464,2465],{},"Sync",[2401,2467,2468],{},"Passive - responds to push\u002Fpull requests",[2401,2470,2471,2474,2475],{},[155,2472,2473],{},"TetherClient::sync()"," or ",[155,2476,2149],{},[2478,2479,2480],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":200,"searchDepth":207,"depth":221,"links":2482},[2483,2484,2490,2496,2503,2504],{"id":145,"depth":221,"text":146},{"id":187,"depth":221,"text":188,"children":2485},[2486,2487,2488,2489],{"id":192,"depth":233,"text":193},{"id":243,"depth":233,"text":244},{"id":548,"depth":233,"text":549},{"id":1071,"depth":233,"text":1072},{"id":1120,"depth":221,"text":1121,"children":2491},[2492,2493,2494,2495],{"id":1124,"depth":233,"text":1125},{"id":1159,"depth":233,"text":1160},{"id":1185,"depth":233,"text":1186},{"id":1636,"depth":233,"text":1637},{"id":1803,"depth":221,"text":1804,"children":2497},[2498,2499,2500,2501,2502],{"id":1807,"depth":233,"text":1808},{"id":1933,"depth":233,"text":1934},{"id":2001,"depth":233,"text":2002},{"id":2096,"depth":233,"text":2097},{"id":2161,"depth":233,"text":2162},{"id":2181,"depth":221,"text":2182},{"id":2377,"depth":221,"text":2378},"Follow a practical Laravel Tether example that builds a task manager with local offline writes, server sync endpoints, scoped pull, and conflicts.","md",null,{},{"title":2510,"description":2505},"Build an Offline-First Laravel Task Manager - Tether Example","-QO7tYPgHvKRpGy_Z1oTfr6tnzsNqdHTOJuZAytZSos",[2513,2507],{"title":108,"path":109,"stem":110,"description":2514,"children":-1},"Transform Tether mutation and snapshot payloads between client and server using client mutation mappers, push mappers, and pull snapshot mappers.",1780481017188]